From 8606bd008c28fc6cb5a2e967f1a2a36615559b9e Mon Sep 17 00:00:00 2001 From: giu Date: Sun, 12 Jan 2025 14:19:21 -0500 Subject: [PATCH 01/20] Updates to Substreams docs and to New Chain Integrations --- website/pages/ar/substreams/sps/_meta.js | 2 +- website/pages/cs/substreams/sps/_meta.js | 2 +- website/pages/de/substreams/sps/_meta.js | 2 +- website/pages/en/_meta.js | 2 +- .../en/indexing/new-chain-integration.mdx | 24 ++----- website/pages/en/substreams/_meta.js | 8 ++- .../assets/publish-package/1_get-token.png | Bin 0 -> 104134 bytes .../assets/publish-package/2_new_token.png | Bin 0 -> 876130 bytes .../assets/publish-package/3_paste_token.png | Bin 0 -> 110187 bytes .../assets/publish-package/4_confirm.png | Bin 0 -> 143329 bytes .../assets/publish-package/5_success.png | Bin 0 -> 145396 bytes .../pages/en/substreams/developing/_meta.js | 5 ++ .../en/substreams/developing/devcontainer.mdx | 39 +++++++++++ .../en/substreams/developing/sinks/_meta.js | 5 ++ .../en/substreams/developing/sinks/sinks.mdx | 43 ++++++++++++ .../{ => developing/sinks}/sps/_meta.js | 0 .../sinks}/sps/introduction.mdx | 14 ++-- .../{ => developing/sinks}/sps/sps-faq.mdx | 0 .../{ => developing/sinks}/sps/triggers.mdx | 0 .../{ => developing/sinks}/sps/tutorial.mdx | 0 .../en/substreams/developing/solana/_meta.js | 5 ++ .../developing/solana/accountchanges.mdx | 59 ++++++++++++++++ .../substreams/developing/solana/solana.mdx | 7 ++ .../developing/solana/transactions.mdx | 66 ++++++++++++++++++ .../substreams/getting-started-substreams.mdx | 36 ++++++++++ website/pages/en/substreams/introduction.mdx | 24 ++----- .../substreams/introductionOld.mdx} | 2 +- website/pages/en/substreams/pubsubstreams.mdx | 46 ++++++++++++ website/pages/es/substreams/sps/_meta.js | 2 +- website/pages/fr/substreams/sps/_meta.js | 2 +- website/pages/hi/substreams/sps/_meta.js | 2 +- website/pages/it/substreams/sps/_meta.js | 2 +- website/pages/ja/substreams/sps/_meta.js | 2 +- website/pages/ko/substreams/sps/_meta.js | 2 +- website/pages/mr/substreams/sps/_meta.js | 2 +- website/pages/nl/substreams/sps/_meta.js | 2 +- website/pages/pl/substreams/sps/_meta.js | 2 +- website/pages/pt/substreams/sps/_meta.js | 2 +- website/pages/ro/substreams/sps/_meta.js | 2 +- website/pages/ru/substreams/sps/_meta.js | 2 +- website/pages/sv/substreams/sps/_meta.js | 2 +- website/pages/sw/substreams/sps/_meta.js | 2 +- website/pages/tr/substreams/sps/_meta.js | 2 +- website/pages/uk/substreams/sps/_meta.js | 2 +- website/pages/ur/substreams/sps/_meta.js | 2 +- website/pages/vi/substreams/sps/_meta.js | 2 +- website/pages/zh/substreams/sps/_meta.js | 2 +- 47 files changed, 362 insertions(+), 67 deletions(-) create mode 100644 website/pages/en/substreams/assets/publish-package/1_get-token.png create mode 100644 website/pages/en/substreams/assets/publish-package/2_new_token.png create mode 100644 website/pages/en/substreams/assets/publish-package/3_paste_token.png create mode 100644 website/pages/en/substreams/assets/publish-package/4_confirm.png create mode 100644 website/pages/en/substreams/assets/publish-package/5_success.png create mode 100644 website/pages/en/substreams/developing/_meta.js create mode 100644 website/pages/en/substreams/developing/devcontainer.mdx create mode 100644 website/pages/en/substreams/developing/sinks/_meta.js create mode 100644 website/pages/en/substreams/developing/sinks/sinks.mdx rename website/pages/en/substreams/{ => developing/sinks}/sps/_meta.js (100%) rename website/pages/en/substreams/{ => developing/sinks}/sps/introduction.mdx (51%) rename website/pages/en/substreams/{ => developing/sinks}/sps/sps-faq.mdx (100%) rename website/pages/en/substreams/{ => developing/sinks}/sps/triggers.mdx (100%) rename website/pages/en/substreams/{ => developing/sinks}/sps/tutorial.mdx (100%) create mode 100644 website/pages/en/substreams/developing/solana/_meta.js create mode 100644 website/pages/en/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/en/substreams/developing/solana/solana.mdx create mode 100644 website/pages/en/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/en/substreams/getting-started-substreams.mdx rename website/pages/{sw/substreams/introduction.mdx => en/substreams/introductionOld.mdx} (98%) create mode 100644 website/pages/en/substreams/pubsubstreams.mdx diff --git a/website/pages/ar/substreams/sps/_meta.js b/website/pages/ar/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/ar/substreams/sps/_meta.js +++ b/website/pages/ar/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/cs/substreams/sps/_meta.js b/website/pages/cs/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/cs/substreams/sps/_meta.js +++ b/website/pages/cs/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/de/substreams/sps/_meta.js b/website/pages/de/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/de/substreams/sps/_meta.js +++ b/website/pages/de/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/en/_meta.js b/website/pages/en/_meta.js index 096e98263be9..b07340209b92 100644 --- a/website/pages/en/_meta.js +++ b/website/pages/en/_meta.js @@ -28,7 +28,7 @@ export default { }, '###3': { type: 'heading', - title: 'Indexing', + title: 'Indexing', }, indexing: { type: 'children', diff --git a/website/pages/en/indexing/new-chain-integration.mdx b/website/pages/en/indexing/new-chain-integration.mdx index 09b74772eff3..faa4b2f117b8 100644 --- a/website/pages/en/indexing/new-chain-integration.mdx +++ b/website/pages/en/indexing/new-chain-integration.mdx @@ -25,17 +25,19 @@ For Graph Node to be able to ingest data from an EVM chain, the RPC node must ex - `eth_getBlockByHash` - `net_version` - `eth_getTransactionReceipt`, in a JSON-RPC batch request -- `trace_filter` *(optionally required for Graph Node to support call handlers)* +- `trace_filter` *(limited tracing and optionally required for Graph Node)* ### 2. Firehose Integration [Firehose](https://firehose.streamingfast.io/firehose-setup/overview) is a next-generation extraction layer. It collects history in flat files and streams in real time. Firehose technology replaces those polling API calls with a stream of data utilizing a push model that sends data to the indexing node faster. This helps increase the speed of syncing and indexing. -The primary method to integrate the Firehose into chains is to use an RPC polling strategy. Our polling algorithm will predict when a new block will arrive and increase the rate at which it checks for a new block near that time, making it a very low-latency and efficient solution. For help with the integration and maintenance of the Firehose, contact the [StreamingFast team](https://www.streamingfast.io/firehose-integration-program). New chains and their integrators will appreciate the [fork awareness](https://substreams.streamingfast.io/documentation/consume/reliability-guarantees) and massive parallelized indexing capabilities that Firehose and Substreams bring to their ecosystem. - > NOTE: All integrations done by the StreamingFast team include maintenance for the Firehose replication protocol into the chain's codebase. StreamingFast tracks any changes and releases binaries when you change code and when StreamingFast changes code. This includes releasing Firehose/Substreams binaries for the protocol, maintaining Substreams modules for the block model of the chain, and releasing binaries for the blockchain node with instrumentation if need be. -#### Specific Firehose Instrumentation for EVM (`geth`) chains +#### Integration for Non-EVM chains + +The primary method to integrate the Firehose into chains is to use an RPC polling strategy. Our polling algorithm will predict when a new block will arrive and increase the rate at which it checks for a new block near that time, making it a very low-latency and efficient solution. For help with the integration and maintenance of the Firehose, contact the [StreamingFast team](https://www.streamingfast.io/firehose-integration-program). New chains and their integrators will appreciate the [fork awareness](https://substreams.streamingfast.io/documentation/consume/reliability-guarantees) and massive parallelized indexing capabilities that Firehose and Substreams bring to their ecosystem. + +#### Specific Instrumentation for EVM (`geth`) chains For EVM chains, there exists a deeper level of data that can be achieved through the `geth` [live-tracer](https://github.com/ethereum/go-ethereum/releases/tag/v1.14.0), a collaboration between Go-Ethereum and StreamingFast, in building a high-throughput and rich transaction tracing system. The Live Tracer is the most comprehensive solution, resulting in [Extended](https://streamingfastio.medium.com/new-block-model-to-accelerate-chain-integration-9f65126e5425) block details. This enables new indexing paradigms, like pattern matching of events based on state changes, calls, parent call trees, or triggering of events based on changes to the actual variables in a smart contract. @@ -56,24 +58,12 @@ While the JSON-RPC and Firehose are both suitable for subgraphs, a Firehose is a Configuring Graph Node is as easy as preparing your local environment. Once your local environment is set, you can test the integration by locally deploying a subgraph. 1. [Clone Graph Node](https://github.com/graphprotocol/graph-node) -2. Modify [this line](https://github.com/graphprotocol/graph-node/blob/master/docker/docker-compose.yml#L22) to include the new network name and the EVM JSON-RPC compliant URL +2. Modify [this line](https://github.com/graphprotocol/graph-node/blob/master/docker/docker-compose.yml#L22) to include the new network name and the EVM JSON-RPC or Firehose compliant URL > Do not change the env var name itself. It must remain `ethereum` even if the network name is different. 3. Run an IPFS node or use the one used by The Graph: https://api.thegraph.com/ipfs/ -### Testing an EVM JSON-RPC by locally deploying a subgraph - -1. Install [graph-cli](https://github.com/graphprotocol/graph-cli) -2. Create a simple example subgraph. Some options are below: - 1. The pre-packed [Gravitar](https://github.com/graphprotocol/example-subgraph/tree/f89bdd4628efa4badae7367d4919b3f648083323) smart contract and subgraph is a good starting point - 2. Bootstrap a local subgraph from any existing smart contract or solidity dev environment [using Hardhat with a Graph plugin](https://github.com/graphprotocol/hardhat-graph) -3. Adapt the resulting `subgraph.yaml` by changing `dataSources.network` to the same name previously passed on to Graph Node. -4. Create your subgraph in Graph Node: `graph create $SUBGRAPH_NAME --node $GRAPH_NODE_ENDPOINT` -5. Publish your subgraph to Graph Node: `graph deploy $SUBGRAPH_NAME --ipfs $IPFS_ENDPOINT --node $GRAPH_NODE_ENDPOINT` - -Graph Node should be syncing the deployed subgraph if there are no errors. Give it time to sync, then send some GraphQL queries to the API endpoint printed in the logs. - ## Substreams-powered Subgraphs For StreamingFast-led Firehose/Substreams integrations, basic support for foundational Substreams modules (e.g. decoded transactions, logs and smart-contract events) and Substreams codegen tools are included. These tools enable the ability to enable [Substreams-powered subgraphs](/substreams/sps/introduction/). Follow the [How-To Guide](https://substreams.streamingfast.io/documentation/how-to-guides/intro-your-first-application) and run `substreams codegen subgraph` to experience the codegen tools for yourself. diff --git a/website/pages/en/substreams/_meta.js b/website/pages/en/substreams/_meta.js index fc586ec6c05b..48cb6da15fca 100644 --- a/website/pages/en/substreams/_meta.js +++ b/website/pages/en/substreams/_meta.js @@ -1,4 +1,6 @@ export default { - introduction: 'Introduction', - sps: 'Substreams-Powered Subgraphs', -} + introduction: 'Introduction to Substreams', + 'getting-started-substreams': 'Quick Start', + 'pubsubstreams': 'Run a Substreams Package', + developing: 'Developing', +} \ No newline at end of file diff --git a/website/pages/en/substreams/assets/publish-package/1_get-token.png b/website/pages/en/substreams/assets/publish-package/1_get-token.png new file mode 100644 index 0000000000000000000000000000000000000000..f2c5a7a7fd753c17cad0f0db96e2fbb43911798c GIT binary patch literal 104134 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ΫzM4%&h;_lhlJ~uE6Et! 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

?k3T5I?Gz!~>*10fu>I!bNi=R(ES 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%0DqIb4AB%Y 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 literal 0 HcmV?d00001 diff --git a/website/pages/en/substreams/assets/publish-package/2_new_token.png b/website/pages/en/substreams/assets/publish-package/2_new_token.png new file mode 100644 index 0000000000000000000000000000000000000000..f5249565940a3ed4165eef785b165c85e84b56e1 GIT binary patch literal 876130 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%0D^Va~zw402!>;H`a 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%0A< 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�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

k~8?Pjao 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�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�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%0AaP>B$H-}g2&Ni;x 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�q!WF{hMelJ`tQ0_!_{2 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 ZKvN!%*@&&i{s#W2C}}7b%0GSi{{Uu&_J#le literal 0 HcmV?d00001 diff --git a/website/pages/en/substreams/assets/publish-package/3_paste_token.png b/website/pages/en/substreams/assets/publish-package/3_paste_token.png new file mode 100644 index 0000000000000000000000000000000000000000..f54ef5f352395ce652de0bccb2b14d07de9600af GIT binary patch literal 110187 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 KK3&f6?*9W~r3{b& literal 0 HcmV?d00001 diff --git a/website/pages/en/substreams/assets/publish-package/4_confirm.png b/website/pages/en/substreams/assets/publish-package/4_confirm.png new file mode 100644 index 0000000000000000000000000000000000000000..b32e56fae04916f8fb405d68c4722bd9bfdb6043 GIT binary patch literal 143329 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�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 $7g81N*+M2j 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 z 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 literal 0 HcmV?d00001 diff --git a/website/pages/en/substreams/assets/publish-package/5_success.png b/website/pages/en/substreams/assets/publish-package/5_success.png new file mode 100644 index 0000000000000000000000000000000000000000..67d5ce01c893618ed06a59853ec8e2a17a907f20 GIT binary patch literal 145396 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 xvnDdY*F!Dhwx57r_(ETE>IB{~rLA0l5GG literal 0 HcmV?d00001 diff --git a/website/pages/en/substreams/developing/_meta.js b/website/pages/en/substreams/developing/_meta.js new file mode 100644 index 000000000000..fd1311970263 --- /dev/null +++ b/website/pages/en/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +export default { + devcontainer: 'Dev Container', + solana: 'Solana', + sinks: 'Sink your Substreams', + } \ No newline at end of file diff --git a/website/pages/en/substreams/developing/devcontainer.mdx b/website/pages/en/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..7ee05d936caf --- /dev/null +++ b/website/pages/en/substreams/developing/devcontainer.mdx @@ -0,0 +1,39 @@ +--- +title: Substreams Dev Container +--- + +The Substreams Dev Container is a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams-starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## First Navigating the Dev Container + +Upon entering the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path, or opt for the automatically generated Substreams paths. Then running `Substreams Build` generates the Protobuf files. + +- **Minimal**: Starts you with the raw block data, this path is for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that is built and maintained by the StreamingFast team. + +To publish your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your Substreams project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more information on configuring a Subgraph sink, see the [Subgraph documentation](https://thegraph.com/docs/en/sps/triggers). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. \ No newline at end of file diff --git a/website/pages/en/substreams/developing/sinks/_meta.js b/website/pages/en/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..fee90128a0b1 --- /dev/null +++ b/website/pages/en/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +export default { + sinks: 'Official Sinks', + sps: 'Substreams-Powered Subgraphs', + } + \ No newline at end of file diff --git a/website/pages/en/substreams/developing/sinks/sinks.mdx b/website/pages/en/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..61dcec7cff6d --- /dev/null +++ b/website/pages/en/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,43 @@ +Once you find a package that fits your needs, you can choose how you want to consume the data. Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +{% hint style="info" %} +**Note**: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. +{% endhint %} + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +{% hint style="success" %} +**Deployable Service**: If you’d like your sink (e.g., SQL or PubSub) to be hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). +{% endhint %} + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +|-----------|---------|------------------|-------------| +| SQL | O | StreamingFast |[substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql)| +| Go SDK | O | StreamingFast |[substreams-sink](https://github.com/streamingfast/substreams-sink)| +| Rust SDK | O | StreamingFast |[substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust)| +| JS SDK | O | StreamingFast |[substreams-js](https://github.com/substreams-js/substreams-js)| +| KV Store | O | StreamingFast |[substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv)| +| Prometheus| O | Pinax |[substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus)| +| Webhook | O | Pinax |[substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook)| +| CSV | O | Pinax |[substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv)| +| PubSub | O | StreamingFast |[substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub)| + +### Community + +| Name | Support | Maintainer | Source Code | +|-----------|---------|------------------|-------------| +| MongoDB | C | Community |[substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb)| +| Files | C | Community |[substreams-sink-files](https://github.com/streamingfast/substreams-sink-files)| +| KV Store | C | Community |[substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv)| +| Prometheus| C | Community |[substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus)| + +* O = Official Support (by one of the main Substreams providers) +* C = Community Support \ No newline at end of file diff --git a/website/pages/en/substreams/sps/_meta.js b/website/pages/en/substreams/developing/sinks/sps/_meta.js similarity index 100% rename from website/pages/en/substreams/sps/_meta.js rename to website/pages/en/substreams/developing/sinks/sps/_meta.js diff --git a/website/pages/en/substreams/sps/introduction.mdx b/website/pages/en/substreams/developing/sinks/sps/introduction.mdx similarity index 51% rename from website/pages/en/substreams/sps/introduction.mdx rename to website/pages/en/substreams/developing/sinks/sps/introduction.mdx index bacd601bd011..36db55e58da7 100644 --- a/website/pages/en/substreams/sps/introduction.mdx +++ b/website/pages/en/substreams/developing/sinks/sps/introduction.mdx @@ -8,12 +8,16 @@ There are two methods of enabling this technology: Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. +Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/en/substreams/sps/sps-faq.mdx b/website/pages/en/substreams/developing/sinks/sps/sps-faq.mdx similarity index 100% rename from website/pages/en/substreams/sps/sps-faq.mdx rename to website/pages/en/substreams/developing/sinks/sps/sps-faq.mdx diff --git a/website/pages/en/substreams/sps/triggers.mdx b/website/pages/en/substreams/developing/sinks/sps/triggers.mdx similarity index 100% rename from website/pages/en/substreams/sps/triggers.mdx rename to website/pages/en/substreams/developing/sinks/sps/triggers.mdx diff --git a/website/pages/en/substreams/sps/tutorial.mdx b/website/pages/en/substreams/developing/sinks/sps/tutorial.mdx similarity index 100% rename from website/pages/en/substreams/sps/tutorial.mdx rename to website/pages/en/substreams/developing/sinks/sps/tutorial.mdx diff --git a/website/pages/en/substreams/developing/solana/_meta.js b/website/pages/en/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..8531f8594b85 --- /dev/null +++ b/website/pages/en/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +export default { + solana: 'Solana Offerings', + transactions: 'Transactions and Instructions', + accountchanges: 'Account Changes' + } \ No newline at end of file diff --git a/website/pages/en/substreams/developing/solana/accountchanges.mdx b/website/pages/en/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..b69be7fed991 --- /dev/null +++ b/website/pages/en/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,59 @@ +# Getting Started with Solana Account Changes + +## Introduction + +In this guide, you will learn how to consume Solana account change data using Substreams. We will walk you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this tutorial, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +{% hint style="info" %} + History for the Solana Account Changes dates as of 2025, block 310629601. +{% endhint %} + +For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance we're omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +## Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, we can set up a connection to the Solana Account Change Substreams feed. + +Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` +This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +This tutorial will continue to guide you through filtering, sinking the data, and setting up reconnection policies. + +## Step 2: Sink the Substreams + +Consume the account stream [directly in your applicaion](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +## Step 3: Setting up a Reconnection Policy + + [Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted, preventing data loss and maintaining a persistent stream. + + The user's primary responsibility when creating or using a sink is to pass a BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` \ No newline at end of file diff --git a/website/pages/en/substreams/developing/solana/solana.mdx b/website/pages/en/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..c887f5a882f3 --- /dev/null +++ b/website/pages/en/substreams/developing/solana/solana.mdx @@ -0,0 +1,7 @@ +With Substreams on Solana you can index [Transaction and Instruction](./transactions.mdx) data as well as [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + +1. History for the Solana Account Changes dates as of 2025, block 310629601. + +2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. + +Test our latency on Solana, measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. \ No newline at end of file diff --git a/website/pages/en/substreams/developing/solana/transactions.mdx b/website/pages/en/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..37e5f1498642 --- /dev/null +++ b/website/pages/en/substreams/developing/solana/transactions.mdx @@ -0,0 +1,66 @@ +In this guide, you'll learn how to initialize a Solana-based Substreams project within the Dev Container (excludes [Account Changes](./accountchanges.mdx)). + +{% hint style="info" %} + If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). +{% endhint %} + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the one that best fits your requirements: + - **sol-minimal**: Creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: Creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: Given an Anchor IDL, create a Substreams that decodes instructions and events. If an IDL isn’t available using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), you’ll need to provide it yourself. + +The modules within Solana Common exclude voting transactions, to benefit from a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +{% hint style="info" %} + To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. +{% endhint %} + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. To learn more about this, visit the [How-to-Guides](../how-to-guides/develop-your-own-substreams/solana/solana.md) + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a Subgraph (known as a [Substreams-powered subgraph](https://thegraph.com/docs/en/sps/introduction/)) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](../how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substreams:SQL](../how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +{% hint style="info" %} +**Note**: Run `help` to better navigate the development environment and check the health of containers. +{% endhint %} + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +### Dev Container Reference + +The [Dev Container Reference](../references/devcontainer-ref.md) helps you navigate the container and its common errors. + +### CLI Reference + +The [CLI reference](../references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. + +### Substreams Components Reference + +The [Components Reference](../references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. \ No newline at end of file diff --git a/website/pages/en/substreams/getting-started-substreams.mdx b/website/pages/en/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..908a05f8f911 --- /dev/null +++ b/website/pages/en/substreams/getting-started-substreams.mdx @@ -0,0 +1,36 @@ +--- +title: Getting Started with Substreams +--- + +Integrating Substreams can be quick and easy. This guide will help you get started with consuming ready-made Substreams packages or developing your own. Substreams are permissionless. Grab a key [here](https://thegraph.market/), no personal information required, and start streaming on-chain data. + +# Build + +## Explore Available Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [**Substreams Registry**](https://substreams.dev) and [sinking them](./developing/sinks/sinks.mdx). The registry lets you search for and find packages that meet your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: +- **[Subgraph](../sps/introduction.mdx)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +

+ +## Optionally Develop Your Own Substreams + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you’ll write functions that extract and filter the data you need from the blockchain. The easiest way to get started is by referring to the [tutorial](https://docs.substreams.dev/tutorials/intro-to-tutorials) section, enabling you to quickly filter data: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](./developing/devcontainer.mdx) to setup your environment and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams). + +## Learn + +- **Substreams Reliability Guarantees**: With a simple reconnection policy, Substreams guarantees you'll [Never Miss Data](https://docs.substreams.dev/reference-material/reliability-guarantees). +- **Substreams Architecture**: For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. \ No newline at end of file diff --git a/website/pages/en/substreams/introduction.mdx b/website/pages/en/substreams/introduction.mdx index 4fd0efb697aa..50b9ce6b497c 100644 --- a/website/pages/en/substreams/introduction.mdx +++ b/website/pages/en/substreams/introduction.mdx @@ -8,7 +8,8 @@ Substreams is a powerful blockchain indexing technology designed to enhance perf - **Accelerated Indexing**: Substreams reduce subgraph indexing time thanks to a parallelized engine, enabling faster data retrieval and processing. - **Multi-Chain Support**: Substreams expand indexing capabilities beyond EVM-based chains, supporting ecosystems like Solana, Injective, Starknet, and Vara. -- **Multi-Sink Support:** Subgraph, Postgres database, Clickhouse, Mongo database +- **Enhanced Data Model**: Substreams provides comprehensive data, including the `trace` level data on EVM or Account Changes on Solana, while efficiently managing forks/disconnections. +- **Multi-Sink Support:** Subgraph, Postgres database, Clickhouse, Mongo database. ## How Substreams Works in 4 Steps @@ -30,23 +31,10 @@ Substreams is a powerful blockchain indexing technology designed to enhance perf 3. **The WASM container is sent to a Substreams endpoint for execution.** The Substreams provider feeds the WASM container with the blockchain data and the transformations are applied. -4. **You select a [sink](https://substreams.streamingfast.io/documentation/consume/other-sinks), a place where you want to send the transformed data** (a Postgres database or a Subgraph, for example). +4. **You select a [sink](https://docs.substreams.dev/how-to-guides/sinks), a place where you want to send the transformed data** (a SQL database or a Subgraph, for example). -## Substreams Documentation +### How Does It Work? -The official Substreams documentation is currently maintained by the StreamingFast team [on the StreamingFast website](https://substreams.streamingfast.io/). +Visit the [Quick Start](./getting-started-substreams.mdx) to begin using Substreams. -To learn about the latest version of Substreams CLI, which enables developers to bootstrap a Substreams project without any code, please check [Substreams Codegen](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6). - -### Getting Started - -- In order to develop and deploy a Substreams, [you must install the Substreams CLI](https://substreams.streamingfast.io/documentation/consume/installing-the-cli). -- Then, run your first Substreams by following the [Quickstart Tutorial](https://substreams.streamingfast.io/documentation/develop/init-project). - -### Expand Your Knowledge - -- Take a look at the [Ethereum Explorer Tutorial](https://substreams.streamingfast.io/tutorials/evm) to learn about the basic transformations you can create with Substreams. - -### Substreams Registry - -A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. Visit [substreams.dev](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. +> Note: The Substreams developer documentation is maintained by the StreamingFast core development team on the [Substreams registry](https://docs.substreams.dev). \ No newline at end of file diff --git a/website/pages/sw/substreams/introduction.mdx b/website/pages/en/substreams/introductionOld.mdx similarity index 98% rename from website/pages/sw/substreams/introduction.mdx rename to website/pages/en/substreams/introductionOld.mdx index 6385439f89f0..4fd0efb697aa 100644 --- a/website/pages/sw/substreams/introduction.mdx +++ b/website/pages/en/substreams/introductionOld.mdx @@ -1,5 +1,5 @@ --- -title: Substreams +title: Introduction to Substreams --- ![Substreams Logo](/img/substreams-logo.png) diff --git a/website/pages/en/substreams/pubsubstreams.mdx b/website/pages/en/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..78a0b3e296df --- /dev/null +++ b/website/pages/en/substreams/pubsubstreams.mdx @@ -0,0 +1,46 @@ +--- +title: Publishing a Substreams Package +--- + +# What is it? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +Visit [substreams.dev](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. + +# Publish a Package + +In this guide, you'll learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +## Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +
+ +## Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +
+ +## Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +
+ +2. Lastly, confirm that you want to publish the package. + +
+ +That's it! You have succesfully published a package in the Substreams registry. \ No newline at end of file diff --git a/website/pages/es/substreams/sps/_meta.js b/website/pages/es/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/es/substreams/sps/_meta.js +++ b/website/pages/es/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/fr/substreams/sps/_meta.js b/website/pages/fr/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/fr/substreams/sps/_meta.js +++ b/website/pages/fr/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/hi/substreams/sps/_meta.js b/website/pages/hi/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/hi/substreams/sps/_meta.js +++ b/website/pages/hi/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/it/substreams/sps/_meta.js b/website/pages/it/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/it/substreams/sps/_meta.js +++ b/website/pages/it/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/ja/substreams/sps/_meta.js b/website/pages/ja/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/ja/substreams/sps/_meta.js +++ b/website/pages/ja/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/ko/substreams/sps/_meta.js b/website/pages/ko/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/ko/substreams/sps/_meta.js +++ b/website/pages/ko/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/mr/substreams/sps/_meta.js b/website/pages/mr/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/mr/substreams/sps/_meta.js +++ b/website/pages/mr/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/nl/substreams/sps/_meta.js b/website/pages/nl/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/nl/substreams/sps/_meta.js +++ b/website/pages/nl/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/pl/substreams/sps/_meta.js b/website/pages/pl/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/pl/substreams/sps/_meta.js +++ b/website/pages/pl/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/pt/substreams/sps/_meta.js b/website/pages/pt/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/pt/substreams/sps/_meta.js +++ b/website/pages/pt/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/ro/substreams/sps/_meta.js b/website/pages/ro/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/ro/substreams/sps/_meta.js +++ b/website/pages/ro/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/ru/substreams/sps/_meta.js b/website/pages/ru/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/ru/substreams/sps/_meta.js +++ b/website/pages/ru/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/sv/substreams/sps/_meta.js b/website/pages/sv/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/sv/substreams/sps/_meta.js +++ b/website/pages/sv/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/sw/substreams/sps/_meta.js b/website/pages/sw/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/sw/substreams/sps/_meta.js +++ b/website/pages/sw/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/tr/substreams/sps/_meta.js b/website/pages/tr/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/tr/substreams/sps/_meta.js +++ b/website/pages/tr/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/uk/substreams/sps/_meta.js b/website/pages/uk/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/uk/substreams/sps/_meta.js +++ b/website/pages/uk/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/ur/substreams/sps/_meta.js b/website/pages/ur/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/ur/substreams/sps/_meta.js +++ b/website/pages/ur/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/vi/substreams/sps/_meta.js b/website/pages/vi/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/vi/substreams/sps/_meta.js +++ b/website/pages/vi/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, diff --git a/website/pages/zh/substreams/sps/_meta.js b/website/pages/zh/substreams/sps/_meta.js index 71552a5e078a..4d3f3456c0c4 100644 --- a/website/pages/zh/substreams/sps/_meta.js +++ b/website/pages/zh/substreams/sps/_meta.js @@ -1,4 +1,4 @@ -import meta from '../../../en/substreams/sps/_meta.js' +import meta from '../../../en/sps/_meta.js' export default { ...meta, From 0102c752f5a1e32ca78dece20cb81660b0c3e0cf Mon Sep 17 00:00:00 2001 From: Idalith Bustos Date: Tue, 21 Jan 2025 14:21:15 -0800 Subject: [PATCH 02/20] First round of copy, formatting, and build edits. --- website/pages/en/_meta.js | 2 +- .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ website/pages/en/substreams/_meta.js | 6 +- .../pages/en/substreams/developing/_meta.js | 8 +- .../en/substreams/developing/devcontainer.mdx | 8 +- .../en/substreams/developing/sinks/_meta.js | 7 +- .../en/substreams/developing/sinks/sinks.mdx | 56 ++--- .../developing/sinks/sps/introduction.mdx | 2 - .../en/substreams/developing/solana/_meta.js | 8 +- .../developing/solana/accountchanges.mdx | 19 +- .../substreams/developing/solana/solana.mdx | 14 +- .../developing/solana/transactions.mdx | 38 ++- .../substreams/getting-started-substreams.mdx | 33 ++- website/pages/en/substreams/introduction.mdx | 50 ++-- .../pages/en/substreams/introductionOld.mdx | 52 ---- website/pages/en/substreams/pubsubstreams.mdx | 22 +- .../img}/1_get-token.png | Bin .../img}/2_new_token.png | Bin .../img}/3_paste_token.png | Bin .../img}/4_confirm.png | Bin .../img}/5_success.png | Bin 21 files changed, 147 insertions(+), 404 deletions(-) delete mode 100644 website/pages/en/subgraphs/cookbook/substreams-powered-subgraphs.mdx delete mode 100644 website/pages/en/substreams/introductionOld.mdx rename website/{pages/en/substreams/assets/publish-package => public/img}/1_get-token.png (100%) rename website/{pages/en/substreams/assets/publish-package => public/img}/2_new_token.png (100%) rename website/{pages/en/substreams/assets/publish-package => public/img}/3_paste_token.png (100%) rename website/{pages/en/substreams/assets/publish-package => public/img}/4_confirm.png (100%) rename website/{pages/en/substreams/assets/publish-package => public/img}/5_success.png (100%) diff --git a/website/pages/en/_meta.js b/website/pages/en/_meta.js index b07340209b92..096e98263be9 100644 --- a/website/pages/en/_meta.js +++ b/website/pages/en/_meta.js @@ -28,7 +28,7 @@ export default { }, '###3': { type: 'heading', - title: 'Indexing', + title: 'Indexing', }, indexing: { type: 'children', diff --git a/website/pages/en/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/en/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/en/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/en/substreams/_meta.js b/website/pages/en/substreams/_meta.js index 48cb6da15fca..735466eadcee 100644 --- a/website/pages/en/substreams/_meta.js +++ b/website/pages/en/substreams/_meta.js @@ -1,6 +1,6 @@ export default { - introduction: 'Introduction to Substreams', 'getting-started-substreams': 'Quick Start', - 'pubsubstreams': 'Run a Substreams Package', + introduction: 'Introduction', developing: 'Developing', -} \ No newline at end of file + pubsubstreams: 'Publishing', +} diff --git a/website/pages/en/substreams/developing/_meta.js b/website/pages/en/substreams/developing/_meta.js index fd1311970263..07ac902ae602 100644 --- a/website/pages/en/substreams/developing/_meta.js +++ b/website/pages/en/substreams/developing/_meta.js @@ -1,5 +1,5 @@ export default { - devcontainer: 'Dev Container', - solana: 'Solana', - sinks: 'Sink your Substreams', - } \ No newline at end of file + devcontainer: 'Dev Container', + solana: 'Solana', + sinks: 'Sink your Substreams', +} diff --git a/website/pages/en/substreams/developing/devcontainer.mdx b/website/pages/en/substreams/developing/devcontainer.mdx index 7ee05d936caf..4bca5dfffe01 100644 --- a/website/pages/en/substreams/developing/devcontainer.mdx +++ b/website/pages/en/substreams/developing/devcontainer.mdx @@ -15,12 +15,12 @@ Upon entering the Dev Container, you can either build or import your own `substr - **Minimal**: Starts you with the raw block data, this path is for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. - **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that is built and maintained by the StreamingFast team. -To publish your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: +To publish your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: - `substreams registry login` - `substreams registry publish` -> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. ## Building a Sink for Your Project @@ -35,5 +35,5 @@ To deploy a Subgraph, you can either run the `graph-node` locally using the `dep ## Common Errors -- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. -- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. \ No newline at end of file +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/en/substreams/developing/sinks/_meta.js b/website/pages/en/substreams/developing/sinks/_meta.js index fee90128a0b1..9b2adb79687e 100644 --- a/website/pages/en/substreams/developing/sinks/_meta.js +++ b/website/pages/en/substreams/developing/sinks/_meta.js @@ -1,5 +1,4 @@ export default { - sinks: 'Official Sinks', - sps: 'Substreams-Powered Subgraphs', - } - \ No newline at end of file + sinks: 'Official Sinks', + sps: 'Substreams-Powered Subgraphs', +} diff --git a/website/pages/en/substreams/developing/sinks/sinks.mdx b/website/pages/en/substreams/developing/sinks/sinks.mdx index 61dcec7cff6d..621e5fed1402 100644 --- a/website/pages/en/substreams/developing/sinks/sinks.mdx +++ b/website/pages/en/substreams/developing/sinks/sinks.mdx @@ -1,43 +1,45 @@ -Once you find a package that fits your needs, you can choose how you want to consume the data. Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. +--- +title: Official Sinks +--- -{% hint style="info" %} -**Note**: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. -{% endhint %} +Once you find a package that fits your needs, you can choose how you want to consume the data. Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +**Note**: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. - [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. - [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. - [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. - [PubSub](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Send data to a PubSub topic. -- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. -{% hint style="success" %} -**Deployable Service**: If you’d like your sink (e.g., SQL or PubSub) to be hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). -{% endhint %} +**Deployable Service**: If you’d like your sink (e.g., SQL or PubSub) to be hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). ## Navigating Sink Repos ### Official -| Name | Support | Maintainer | Source Code | -|-----------|---------|------------------|-------------| -| SQL | O | StreamingFast |[substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql)| -| Go SDK | O | StreamingFast |[substreams-sink](https://github.com/streamingfast/substreams-sink)| -| Rust SDK | O | StreamingFast |[substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust)| -| JS SDK | O | StreamingFast |[substreams-js](https://github.com/substreams-js/substreams-js)| -| KV Store | O | StreamingFast |[substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv)| -| Prometheus| O | Pinax |[substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus)| -| Webhook | O | Pinax |[substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook)| -| CSV | O | Pinax |[substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv)| -| PubSub | O | StreamingFast |[substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub)| +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | ### Community -| Name | Support | Maintainer | Source Code | -|-----------|---------|------------------|-------------| -| MongoDB | C | Community |[substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb)| -| Files | C | Community |[substreams-sink-files](https://github.com/streamingfast/substreams-sink-files)| -| KV Store | C | Community |[substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv)| -| Prometheus| C | Community |[substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus)| +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | -* O = Official Support (by one of the main Substreams providers) -* C = Community Support \ No newline at end of file +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/en/substreams/developing/sinks/sps/introduction.mdx b/website/pages/en/substreams/developing/sinks/sps/introduction.mdx index 36db55e58da7..847283da9fd1 100644 --- a/website/pages/en/substreams/developing/sinks/sps/introduction.mdx +++ b/website/pages/en/substreams/developing/sinks/sps/introduction.mdx @@ -19,5 +19,3 @@ Visit the following links for tutorials on using code-generation tooling to buil - [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) - [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) - [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) - - diff --git a/website/pages/en/substreams/developing/solana/_meta.js b/website/pages/en/substreams/developing/solana/_meta.js index 8531f8594b85..8fa01df2bab6 100644 --- a/website/pages/en/substreams/developing/solana/_meta.js +++ b/website/pages/en/substreams/developing/solana/_meta.js @@ -1,5 +1,5 @@ export default { - solana: 'Solana Offerings', - transactions: 'Transactions and Instructions', - accountchanges: 'Account Changes' - } \ No newline at end of file + solana: 'Solana Offerings', + transactions: 'Transactions and Instructions', + accountchanges: 'Account Changes', +} diff --git a/website/pages/en/substreams/developing/solana/accountchanges.mdx b/website/pages/en/substreams/developing/solana/accountchanges.mdx index b69be7fed991..a6090bcb56d3 100644 --- a/website/pages/en/substreams/developing/solana/accountchanges.mdx +++ b/website/pages/en/substreams/developing/solana/accountchanges.mdx @@ -1,4 +1,8 @@ -# Getting Started with Solana Account Changes +--- +title: Getting Started with Solana Account Changes +--- + +## Getting Started with Solana Account Changes ## Introduction @@ -6,9 +10,7 @@ In this guide, you will learn how to consume Solana account change data using Su By the end of this tutorial, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. -{% hint style="info" %} - History for the Solana Account Changes dates as of 2025, block 310629601. -{% endhint %} +History for the Solana Account Changes dates as of 2025, block 310629601. For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance we're omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). @@ -29,6 +31,7 @@ Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/ ```bash substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" ``` + This command will stream account changes directly to your terminal. ```bash @@ -45,9 +48,9 @@ Consume the account stream [directly in your applicaion](../../how-to-guides/sin ## Step 3: Setting up a Reconnection Policy - [Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted, preventing data loss and maintaining a persistent stream. - - The user's primary responsibility when creating or using a sink is to pass a BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted, preventing data loss and maintaining a persistent stream. + +The user's primary responsibility when creating or using a sink is to pass a BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: ```go import ( @@ -56,4 +59,4 @@ import ( type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error -``` \ No newline at end of file +``` diff --git a/website/pages/en/substreams/developing/solana/solana.mdx b/website/pages/en/substreams/developing/solana/solana.mdx index c887f5a882f3..177ed4714191 100644 --- a/website/pages/en/substreams/developing/solana/solana.mdx +++ b/website/pages/en/substreams/developing/solana/solana.mdx @@ -1,7 +1,13 @@ -With Substreams on Solana you can index [Transaction and Instruction](./transactions.mdx) data as well as [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: +--- +title: Solana +--- -1. History for the Solana Account Changes dates as of 2025, block 310629601. +## Overview -2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +With Substreams on Solana you can index [Transaction and Instruction](./transactions.mdx) data as well as [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: -Test our latency on Solana, measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. \ No newline at end of file +1. History for the Solana Account Changes dates as of 2025, block 310629601. + +2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. + +Test our latency on Solana, measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/en/substreams/developing/solana/transactions.mdx b/website/pages/en/substreams/developing/solana/transactions.mdx index 37e5f1498642..106ded6d94c3 100644 --- a/website/pages/en/substreams/developing/solana/transactions.mdx +++ b/website/pages/en/substreams/developing/solana/transactions.mdx @@ -1,31 +1,31 @@ +--- +title: Solana Transactions +--- + In this guide, you'll learn how to initialize a Solana-based Substreams project within the Dev Container (excludes [Account Changes](./accountchanges.mdx)). -{% hint style="info" %} - If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). -{% endhint %} +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). ## Step 1: Initialize Your Solana Substreams Project 1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. 2. Running `substreams init` will give you the option to choose between two Solana project options. Select the one that best fits your requirements: - - **sol-minimal**: Creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, you can navigate to the `substreams.yaml` (the manifest) to modify the input. - - **sol-transactions**: Creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). - - **sol-anchor-beta**: Given an Anchor IDL, create a Substreams that decodes instructions and events. If an IDL isn’t available using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), you’ll need to provide it yourself. + - **sol-minimal**: Creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: Creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: Given an Anchor IDL, create a Substreams that decodes instructions and events. If an IDL isn’t available using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), you’ll need to provide it yourself. The modules within Solana Common exclude voting transactions, to benefit from a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. -{% hint style="info" %} - To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. -{% endhint %} - +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + ## Step 2: Visualize the Data 1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. 2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. -## Step 2.5: (Optionally) Transform the Data +## Step 2.5: (Optionally) Transform the Data Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. To learn more about this, visit the [How-to-Guides](../how-to-guides/develop-your-own-substreams/solana/solana.md) @@ -35,19 +35,17 @@ To make your Substreams queryable (as opposed to [direct streaming](../how-to-gu ### Subgraph -1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. 2. Create your [subgraph mappings](../how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. -3. Deploy +3. Deploy ### SQL -1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. -2. Run `substreams build` build the [Substreams:SQL](../how-to-guides/sinks/sql/sql-sink.md) sink. +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substreams:SQL](../how-to-guides/sinks/sql/sql-sink.md) sink. 3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. -{% hint style="info" %} -**Note**: Run `help` to better navigate the development environment and check the health of containers. -{% endhint %} +**Note**: Run `help` to better navigate the development environment and check the health of containers. ## Additional Resources @@ -55,7 +53,7 @@ You may find these additional resources helpful for developing your first Solana ### Dev Container Reference -The [Dev Container Reference](../references/devcontainer-ref.md) helps you navigate the container and its common errors. +The [Dev Container Reference](../references/devcontainer-ref.md) helps you navigate the container and its common errors. ### CLI Reference @@ -63,4 +61,4 @@ The [CLI reference](../references/cli/command-line-interface.md) lets you explor ### Substreams Components Reference -The [Components Reference](../references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. \ No newline at end of file +The [Components Reference](../references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/en/substreams/getting-started-substreams.mdx b/website/pages/en/substreams/getting-started-substreams.mdx index 908a05f8f911..59ccfe85b41b 100644 --- a/website/pages/en/substreams/getting-started-substreams.mdx +++ b/website/pages/en/substreams/getting-started-substreams.mdx @@ -1,26 +1,33 @@ --- -title: Getting Started with Substreams +title: Substreams Quick Start --- -Integrating Substreams can be quick and easy. This guide will help you get started with consuming ready-made Substreams packages or developing your own. Substreams are permissionless. Grab a key [here](https://thegraph.market/), no personal information required, and start streaming on-chain data. +Discover how to utilize ready-to-use substream packages or develop your own. -# Build +## Overview -## Explore Available Substreams Packages +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. -There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [**Substreams Registry**](https://substreams.dev) and [sinking them](./developing/sinks/sinks.mdx). The registry lets you search for and find packages that meet your needs. +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. Once you find a package that fits your needs, you can choose how you want to consume the data: + - **[Subgraph](../sps/introduction.mdx)**: Configure an API to meet your data needs and host it on The Graph Network. - **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. - **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. - **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. -
+
+ +
-## Optionally Develop Your Own Substreams +### Develop Your Own -If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you’ll write functions that extract and filter the data you need from the blockchain. The easiest way to get started is by referring to the [tutorial](https://docs.substreams.dev/tutorials/intro-to-tutorials) section, enabling you to quickly filter data: +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: - [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) - [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) @@ -28,9 +35,11 @@ If you can't find a Substreams package that meets your specific needs, you can d - [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) - [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) -To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](./developing/devcontainer.mdx) to setup your environment and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams). +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. -## Learn +## Additional Resources -- **Substreams Reliability Guarantees**: With a simple reconnection policy, Substreams guarantees you'll [Never Miss Data](https://docs.substreams.dev/reference-material/reliability-guarantees). -- **Substreams Architecture**: For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. \ No newline at end of file +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/en/substreams/introduction.mdx b/website/pages/en/substreams/introduction.mdx index 50b9ce6b497c..e0844e58efa4 100644 --- a/website/pages/en/substreams/introduction.mdx +++ b/website/pages/en/substreams/introduction.mdx @@ -4,37 +4,41 @@ title: Introduction to Substreams ![Substreams Logo](/img/substreams-logo.png) -Substreams is a powerful blockchain indexing technology designed to enhance performance and scalability within The Graph Network. It offers the following features: +To start coding right away, check out the [Substreams Quick Start](/substreams/getting-started-substreams/). -- **Accelerated Indexing**: Substreams reduce subgraph indexing time thanks to a parallelized engine, enabling faster data retrieval and processing. -- **Multi-Chain Support**: Substreams expand indexing capabilities beyond EVM-based chains, supporting ecosystems like Solana, Injective, Starknet, and Vara. -- **Enhanced Data Model**: Substreams provides comprehensive data, including the `trace` level data on EVM or Account Changes on Solana, while efficiently managing forks/disconnections. -- **Multi-Sink Support:** Subgraph, Postgres database, Clickhouse, Mongo database. +## Overview -## How Substreams Works in 4 Steps +Substreams is a powerful parallel blockchain indexing technology designed to enhance performance and scalability within The Graph Network. + +## Substreams Capabilities -1. **You write a Rust program, which defines the transformations that you want to apply to the blockchain data.** For example, the following Rust function extracts relevant information from an Ethereum block (number, hash, and parent hash). +- **Accelerated Indexing**: Boost subgraph indexing time with a parallelized engine for quicker data retrieval and processing. +- **Multi-Chain Support**: Expand indexing capabilities beyond EVM-based chains, supporting ecosystems like Solana, Injective, Starknet, and Vara. +- **Enhanced Data Model**: Access comprehensive data, including the `trace` level data on EVM or Account Changes on Solana, while efficiently managing forks/disconnections. +- **Multi-Sink Support:** Support for Subgraph, Postgres database, Clickhouse, Mongo database. + +## How Substreams Works in 4 Steps - ```rust - fn get_my_block(blk: Block) -> Result { - let header = blk.header.as_ref().unwrap(); +1. You write a Rust program, which defines the transformations that you want to apply to the blockchain data. For example, the following Rust function extracts relevant information from an Ethereum block (number, hash, and parent hash). - Ok(MyBlock { - number: blk.number, - hash: Hex::encode(&blk.hash), - parent_hash: Hex::encode(&header.parent_hash), - }) - } - ``` +```rust +fn get_my_block(blk: Block) -> Result { + let header = blk.header.as_ref().unwrap(); -2. **You wrap up your Rust program into a WASM module just by running a single CLI command.** + Ok(MyBlock { + number: blk.number, + hash: Hex::encode(&blk.hash), + parent_hash: Hex::encode(&header.parent_hash), + }) +} +``` -3. **The WASM container is sent to a Substreams endpoint for execution.** The Substreams provider feeds the WASM container with the blockchain data and the transformations are applied. +2. You wrap up your Rust program into a WASM module just by running a single CLI command. -4. **You select a [sink](https://docs.substreams.dev/how-to-guides/sinks), a place where you want to send the transformed data** (a SQL database or a Subgraph, for example). +3. The WASM container is sent to a Substreams endpoint for execution. The Substreams provider feeds the WASM container with the blockchain data and the transformations are applied. -### How Does It Work? +4. You select a [sink](https://docs.substreams.dev/how-to-guides/sinks), a place where you want to send the transformed data (a SQL database or a Subgraph, for example). -Visit the [Quick Start](./getting-started-substreams.mdx) to begin using Substreams. +## Additional Resources -> Note: The Substreams developer documentation is maintained by the StreamingFast core development team on the [Substreams registry](https://docs.substreams.dev). \ No newline at end of file +All Substreams developer documentation is maintained by the StreamingFast core development team on the [Substreams registry](https://docs.substreams.dev). diff --git a/website/pages/en/substreams/introductionOld.mdx b/website/pages/en/substreams/introductionOld.mdx deleted file mode 100644 index 4fd0efb697aa..000000000000 --- a/website/pages/en/substreams/introductionOld.mdx +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Introduction to Substreams ---- - -![Substreams Logo](/img/substreams-logo.png) - -Substreams is a powerful blockchain indexing technology designed to enhance performance and scalability within The Graph Network. It offers the following features: - -- **Accelerated Indexing**: Substreams reduce subgraph indexing time thanks to a parallelized engine, enabling faster data retrieval and processing. -- **Multi-Chain Support**: Substreams expand indexing capabilities beyond EVM-based chains, supporting ecosystems like Solana, Injective, Starknet, and Vara. -- **Multi-Sink Support:** Subgraph, Postgres database, Clickhouse, Mongo database - -## How Substreams Works in 4 Steps - -1. **You write a Rust program, which defines the transformations that you want to apply to the blockchain data.** For example, the following Rust function extracts relevant information from an Ethereum block (number, hash, and parent hash). - - ```rust - fn get_my_block(blk: Block) -> Result { - let header = blk.header.as_ref().unwrap(); - - Ok(MyBlock { - number: blk.number, - hash: Hex::encode(&blk.hash), - parent_hash: Hex::encode(&header.parent_hash), - }) - } - ``` - -2. **You wrap up your Rust program into a WASM module just by running a single CLI command.** - -3. **The WASM container is sent to a Substreams endpoint for execution.** The Substreams provider feeds the WASM container with the blockchain data and the transformations are applied. - -4. **You select a [sink](https://substreams.streamingfast.io/documentation/consume/other-sinks), a place where you want to send the transformed data** (a Postgres database or a Subgraph, for example). - -## Substreams Documentation - -The official Substreams documentation is currently maintained by the StreamingFast team [on the StreamingFast website](https://substreams.streamingfast.io/). - -To learn about the latest version of Substreams CLI, which enables developers to bootstrap a Substreams project without any code, please check [Substreams Codegen](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6). - -### Getting Started - -- In order to develop and deploy a Substreams, [you must install the Substreams CLI](https://substreams.streamingfast.io/documentation/consume/installing-the-cli). -- Then, run your first Substreams by following the [Quickstart Tutorial](https://substreams.streamingfast.io/documentation/develop/init-project). - -### Expand Your Knowledge - -- Take a look at the [Ethereum Explorer Tutorial](https://substreams.streamingfast.io/tutorials/evm) to learn about the basic transformations you can create with Substreams. - -### Substreams Registry - -A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. Visit [substreams.dev](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/en/substreams/pubsubstreams.mdx b/website/pages/en/substreams/pubsubstreams.mdx index 78a0b3e296df..1d246ee233ac 100644 --- a/website/pages/en/substreams/pubsubstreams.mdx +++ b/website/pages/en/substreams/pubsubstreams.mdx @@ -2,13 +2,13 @@ title: Publishing a Substreams Package --- -# What is it? +## What is it? -A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. Visit [substreams.dev](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. -# Publish a Package +## Publish a Package In this guide, you'll learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). @@ -17,30 +17,32 @@ In this guide, you'll learn how to publish a Substreams package to the [Substrea - You must have the Substreams CLI installed. - You must have a Substreams package (`.spkg`) that you want to publish. -## Step 1: Run the `substreams publish` Command +### Step 1: Run the `substreams publish` Command 1. In a command-line terminal, run `substreams publish .spkg`. 2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. -
+![get token](/img/1_get-token.png) -## Step 2: Get a Token in the Substreams Registry +### Step 2: Get a Token in the Substreams Registry 1. In the Substreams Registry, log in with your GitHub account. 2. Create a new token and copy it in a safe location. -
+![new token](/img/2_new_token.png) ## Step 3: Authenticate in the Substreams CLI 1. Back in the Substreams CLI, paste the previously generated token. -
+![paste token](/img/3_paste_token.png) 2. Lastly, confirm that you want to publish the package. -
+![confirm](/img/4_confirm.png) -That's it! You have succesfully published a package in the Substreams registry. \ No newline at end of file +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) diff --git a/website/pages/en/substreams/assets/publish-package/1_get-token.png b/website/public/img/1_get-token.png similarity index 100% rename from website/pages/en/substreams/assets/publish-package/1_get-token.png rename to website/public/img/1_get-token.png diff --git a/website/pages/en/substreams/assets/publish-package/2_new_token.png b/website/public/img/2_new_token.png similarity index 100% rename from website/pages/en/substreams/assets/publish-package/2_new_token.png rename to website/public/img/2_new_token.png diff --git a/website/pages/en/substreams/assets/publish-package/3_paste_token.png b/website/public/img/3_paste_token.png similarity index 100% rename from website/pages/en/substreams/assets/publish-package/3_paste_token.png rename to website/public/img/3_paste_token.png diff --git a/website/pages/en/substreams/assets/publish-package/4_confirm.png b/website/public/img/4_confirm.png similarity index 100% rename from website/pages/en/substreams/assets/publish-package/4_confirm.png rename to website/public/img/4_confirm.png diff --git a/website/pages/en/substreams/assets/publish-package/5_success.png b/website/public/img/5_success.png similarity index 100% rename from website/pages/en/substreams/assets/publish-package/5_success.png rename to website/public/img/5_success.png From 337a73b639e9d7dfd0ab017fc888169468e383b9 Mon Sep 17 00:00:00 2001 From: Idalith Bustos Date: Tue, 21 Jan 2025 15:11:33 -0800 Subject: [PATCH 03/20] quick-start, intro, and publishing done --- .../substreams/getting-started-substreams.mdx | 10 +++------- website/pages/en/substreams/introduction.mdx | 6 +++--- website/pages/en/substreams/pubsubstreams.mdx | 18 +++++++++++------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/website/pages/en/substreams/getting-started-substreams.mdx b/website/pages/en/substreams/getting-started-substreams.mdx index 59ccfe85b41b..4d06508f31eb 100644 --- a/website/pages/en/substreams/getting-started-substreams.mdx +++ b/website/pages/en/substreams/getting-started-substreams.mdx @@ -16,24 +16,20 @@ There are many ready-to-use Substreams packages available. You can explore these Once you find a package that fits your needs, you can choose how you want to consume the data: -- **[Subgraph](../sps/introduction.mdx)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. - **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. - **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. - **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. -
- -
- ### Develop Your Own If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: - [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) -- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) - [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) - [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) -- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). diff --git a/website/pages/en/substreams/introduction.mdx b/website/pages/en/substreams/introduction.mdx index e0844e58efa4..25fcfa5a5c2c 100644 --- a/website/pages/en/substreams/introduction.mdx +++ b/website/pages/en/substreams/introduction.mdx @@ -14,8 +14,8 @@ Substreams is a powerful parallel blockchain indexing technology designed to enh - **Accelerated Indexing**: Boost subgraph indexing time with a parallelized engine for quicker data retrieval and processing. - **Multi-Chain Support**: Expand indexing capabilities beyond EVM-based chains, supporting ecosystems like Solana, Injective, Starknet, and Vara. -- **Enhanced Data Model**: Access comprehensive data, including the `trace` level data on EVM or Account Changes on Solana, while efficiently managing forks/disconnections. -- **Multi-Sink Support:** Support for Subgraph, Postgres database, Clickhouse, Mongo database. +- **Enhanced Data Model**: Access comprehensive data, including the `trace` level data on EVM or account changes on Solana, while efficiently managing forks/disconnections. +- **Multi-Sink Support:** For Subgraph, Postgres database, Clickhouse, and Mongo database. ## How Substreams Works in 4 Steps @@ -37,7 +37,7 @@ fn get_my_block(blk: Block) -> Result { 3. The WASM container is sent to a Substreams endpoint for execution. The Substreams provider feeds the WASM container with the blockchain data and the transformations are applied. -4. You select a [sink](https://docs.substreams.dev/how-to-guides/sinks), a place where you want to send the transformed data (a SQL database or a Subgraph, for example). +4. You select a [sink](https://docs.substreams.dev/how-to-guides/sinks), a place where you want to send the transformed data (for example a SQL database or a Subgraph). ## Additional Resources diff --git a/website/pages/en/substreams/pubsubstreams.mdx b/website/pages/en/substreams/pubsubstreams.mdx index 1d246ee233ac..3c02d60f9ffd 100644 --- a/website/pages/en/substreams/pubsubstreams.mdx +++ b/website/pages/en/substreams/pubsubstreams.mdx @@ -2,17 +2,17 @@ title: Publishing a Substreams Package --- -## What is it? +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). -A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. +## Overview -Visit [substreams.dev](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. +### What is a package? -## Publish a Package +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. -In this guide, you'll learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). +## Publish a Package -## Prerequisites +### Prerequisites - You must have the Substreams CLI installed. - You must have a Substreams package (`.spkg`) that you want to publish. @@ -33,7 +33,7 @@ In this guide, you'll learn how to publish a Substreams package to the [Substrea ![new token](/img/2_new_token.png) -## Step 3: Authenticate in the Substreams CLI +### Step 3: Authenticate in the Substreams CLI 1. Back in the Substreams CLI, paste the previously generated token. @@ -46,3 +46,7 @@ In this guide, you'll learn how to publish a Substreams package to the [Substrea That's it! You have succesfully published a package in the Substreams registry. ![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. From af993af2084715a768266820f0100e4464b66d04 Mon Sep 17 00:00:00 2001 From: Idalith Bustos Date: Tue, 21 Jan 2025 16:58:06 -0800 Subject: [PATCH 04/20] Dev Container, Solana, Trans copy edits done. Found several broken links need to be fixed, but need to identify source. --- .../en/substreams/developing/devcontainer.mdx | 24 +++++++---- .../substreams/developing/solana/solana.mdx | 14 ++++--- .../developing/solana/transactions.mdx | 40 +++++++++---------- 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/website/pages/en/substreams/developing/devcontainer.mdx b/website/pages/en/substreams/developing/devcontainer.mdx index 4bca5dfffe01..4cadae4a3ebe 100644 --- a/website/pages/en/substreams/developing/devcontainer.mdx +++ b/website/pages/en/substreams/developing/devcontainer.mdx @@ -2,20 +2,28 @@ title: Substreams Dev Container --- -The Substreams Dev Container is a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams-starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. ## Prerequisites - Ensure Docker and VS Code are up-to-date. -## First Navigating the Dev Container +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. -Upon entering the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path, or opt for the automatically generated Substreams paths. Then running `Substreams Build` generates the Protobuf files. +### Options -- **Minimal**: Starts you with the raw block data, this path is for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. -- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that is built and maintained by the StreamingFast team. +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. -To publish your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: - `substreams registry login` - `substreams registry publish` @@ -24,9 +32,9 @@ To publish your work with the broader community, publish your `.spkg` to [Substr ## Building a Sink for Your Project -You can configure your Substreams project to query data either through a Subgraph or directly from an SQL database: +You can configure your project to query data either through a Subgraph or directly from an SQL database: -- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more information on configuring a Subgraph sink, see the [Subgraph documentation](https://thegraph.com/docs/en/sps/triggers). +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). - **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). ## Deployment Options diff --git a/website/pages/en/substreams/developing/solana/solana.mdx b/website/pages/en/substreams/developing/solana/solana.mdx index 177ed4714191..2b5e975a1f6f 100644 --- a/website/pages/en/substreams/developing/solana/solana.mdx +++ b/website/pages/en/substreams/developing/solana/solana.mdx @@ -2,12 +2,14 @@ title: Solana --- -## Overview - -With Substreams on Solana you can index [Transaction and Instruction](./transactions.mdx) data as well as [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: +Enhance your Solana built with Substreams. -1. History for the Solana Account Changes dates as of 2025, block 310629601. +## Overview -2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +With Substreams on Solana, you can: -Test our latency on Solana, measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/en/substreams/developing/solana/transactions.mdx b/website/pages/en/substreams/developing/solana/transactions.mdx index 106ded6d94c3..4f406826a957 100644 --- a/website/pages/en/substreams/developing/solana/transactions.mdx +++ b/website/pages/en/substreams/developing/solana/transactions.mdx @@ -2,7 +2,11 @@ title: Solana Transactions --- -In this guide, you'll learn how to initialize a Solana-based Substreams project within the Dev Container (excludes [Account Changes](./accountchanges.mdx)). +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). @@ -10,12 +14,12 @@ If you prefer to begin locally within your terminal rather than through the Dev 1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. -2. Running `substreams init` will give you the option to choose between two Solana project options. Select the one that best fits your requirements: - - **sol-minimal**: Creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, you can navigate to the `substreams.yaml` (the manifest) to modify the input. - - **sol-transactions**: Creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). - - **sol-anchor-beta**: Given an Anchor IDL, create a Substreams that decodes instructions and events. If an IDL isn’t available using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), you’ll need to provide it yourself. +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. -The modules within Solana Common exclude voting transactions, to benefit from a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. @@ -27,38 +31,30 @@ To access voting transactions, use the full Solana block, `sf.solana.type.v1.Blo ## Step 2.5: (Optionally) Transform the Data -Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. To learn more about this, visit the [How-to-Guides](../how-to-guides/develop-your-own-substreams/solana/solana.md) +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. ## Step 3: Load the Data -To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a Subgraph (known as a [Substreams-powered subgraph](https://thegraph.com/docs/en/sps/introduction/)) or SQL-DB sink. +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. ### Subgraph 1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. -2. Create your [subgraph mappings](../how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. 3. Deploy ### SQL 1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. -2. Run `substreams build` build the [Substreams:SQL](../how-to-guides/sinks/sql/sql-sink.md) sink. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. 3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. -**Note**: Run `help` to better navigate the development environment and check the health of containers. +> Note: Run `help` to better navigate the development environment and check the health of containers. ## Additional Resources You may find these additional resources helpful for developing your first Solana application. -### Dev Container Reference - -The [Dev Container Reference](../references/devcontainer-ref.md) helps you navigate the container and its common errors. - -### CLI Reference - -The [CLI reference](../references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. - -### Substreams Components Reference - -The [Components Reference](../references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. From c8434ff5420e2efea50d489125d91cdfbf70a9c5 Mon Sep 17 00:00:00 2001 From: Idalith Bustos Date: Tue, 21 Jan 2025 17:22:31 -0800 Subject: [PATCH 05/20] Solana Account Changes & Sinks done (more broken links need fixing) --- .../en/substreams/developing/sinks/sinks.mdx | 14 +++++--- .../developing/solana/accountchanges.mdx | 36 +++++++++---------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/website/pages/en/substreams/developing/sinks/sinks.mdx b/website/pages/en/substreams/developing/sinks/sinks.mdx index 621e5fed1402..0429bd56ce34 100644 --- a/website/pages/en/substreams/developing/sinks/sinks.mdx +++ b/website/pages/en/substreams/developing/sinks/sinks.mdx @@ -2,19 +2,25 @@ title: Official Sinks --- -Once you find a package that fits your needs, you can choose how you want to consume the data. Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. ## Sinks -**Note**: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. - [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. - [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. - [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. -- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Send data to a PubSub topic. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. - [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. -**Deployable Service**: If you’d like your sink (e.g., SQL or PubSub) to be hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). ## Navigating Sink Repos diff --git a/website/pages/en/substreams/developing/solana/accountchanges.mdx b/website/pages/en/substreams/developing/solana/accountchanges.mdx index a6090bcb56d3..505d27d28db4 100644 --- a/website/pages/en/substreams/developing/solana/accountchanges.mdx +++ b/website/pages/en/substreams/developing/solana/accountchanges.mdx @@ -1,20 +1,22 @@ --- -title: Getting Started with Solana Account Changes +title: Solana Account Changes --- -## Getting Started with Solana Account Changes +Learn how to consume Solana account change data using Substreams. ## Introduction -In this guide, you will learn how to consume Solana account change data using Substreams. We will walk you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. -By the end of this tutorial, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. -History for the Solana Account Changes dates as of 2025, block 310629601. +- History for the Solana Account Changes dates as of 2025, block 310629601. -For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance we're omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). -## Prerequisites +## Getting Started + +### Prerequisites Before you begin, ensure that you have the following: @@ -22,17 +24,17 @@ Before you begin, ensure that you have the following: 2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. 3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). -## Step 1: Set Up a Connection to Solana Account Change Substreams +### Step 1: Set Up a Connection to Solana Account Change Substreams -Now that you have Substreams CLI installed, we can set up a connection to the Solana Account Change Substreams feed. +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. -Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. ```bash substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" ``` -This command will stream account changes directly to your terminal. +- This command will stream account changes directly to your terminal. ```bash substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock @@ -40,17 +42,15 @@ substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. -This tutorial will continue to guide you through filtering, sinking the data, and setting up reconnection policies. - -## Step 2: Sink the Substreams +### Step 2: Sink the Substreams -Consume the account stream [directly in your applicaion](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). -## Step 3: Setting up a Reconnection Policy +### Step 3: Setting up a Reconnection Policy -[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted, preventing data loss and maintaining a persistent stream. +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. -The user's primary responsibility when creating or using a sink is to pass a BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: ```go import ( From ad77dcd28e1376b3f0a1932f558a6225915a5ac8 Mon Sep 17 00:00:00 2001 From: Idalith Bustos Date: Wed, 22 Jan 2025 16:41:01 -0800 Subject: [PATCH 06/20] adding sps section (as requested) & some copy edits --- website/pages/en/_meta.js | 18 +++++++++--- .../developing/sinks => }/sps/_meta.js | 0 website/pages/en/sps/introduction.mdx | 29 +++++++++++++++++++ .../developing/sinks => }/sps/sps-faq.mdx | 0 .../developing/sinks => }/sps/triggers.mdx | 0 .../developing/sinks => }/sps/tutorial.mdx | 0 .../en/substreams/developing/sinks/_meta.js | 1 - .../developing/sinks/sps/introduction.mdx | 21 -------------- 8 files changed, 43 insertions(+), 26 deletions(-) rename website/pages/en/{substreams/developing/sinks => }/sps/_meta.js (100%) create mode 100644 website/pages/en/sps/introduction.mdx rename website/pages/en/{substreams/developing/sinks => }/sps/sps-faq.mdx (100%) rename website/pages/en/{substreams/developing/sinks => }/sps/triggers.mdx (100%) rename website/pages/en/{substreams/developing/sinks => }/sps/tutorial.mdx (100%) delete mode 100644 website/pages/en/substreams/developing/sinks/sps/introduction.mdx diff --git a/website/pages/en/_meta.js b/website/pages/en/_meta.js index 096e98263be9..a2ec755c2c7c 100644 --- a/website/pages/en/_meta.js +++ b/website/pages/en/_meta.js @@ -18,9 +18,9 @@ export default { }, '###2': { type: 'heading', - title: 'Substreams', + title: 'Substreams powered Subgraphs', }, - substreams: { + sps: { type: 'children', }, '---3': { @@ -28,15 +28,25 @@ export default { }, '###3': { type: 'heading', - title: 'Indexing', + title: 'Substreams', }, - indexing: { + substreams: { type: 'children', }, '---4': { type: 'separator', }, '###4': { + type: 'heading', + title: 'Indexing', + }, + indexing: { + type: 'children', + }, + '---5': { + type: 'separator', + }, + '###5': { type: 'heading', title: 'Resources', }, diff --git a/website/pages/en/substreams/developing/sinks/sps/_meta.js b/website/pages/en/sps/_meta.js similarity index 100% rename from website/pages/en/substreams/developing/sinks/sps/_meta.js rename to website/pages/en/sps/_meta.js diff --git a/website/pages/en/sps/introduction.mdx b/website/pages/en/sps/introduction.mdx new file mode 100644 index 000000000000..427576249d79 --- /dev/null +++ b/website/pages/en/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using Substreams to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +## Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +## Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/en/substreams/developing/sinks/sps/sps-faq.mdx b/website/pages/en/sps/sps-faq.mdx similarity index 100% rename from website/pages/en/substreams/developing/sinks/sps/sps-faq.mdx rename to website/pages/en/sps/sps-faq.mdx diff --git a/website/pages/en/substreams/developing/sinks/sps/triggers.mdx b/website/pages/en/sps/triggers.mdx similarity index 100% rename from website/pages/en/substreams/developing/sinks/sps/triggers.mdx rename to website/pages/en/sps/triggers.mdx diff --git a/website/pages/en/substreams/developing/sinks/sps/tutorial.mdx b/website/pages/en/sps/tutorial.mdx similarity index 100% rename from website/pages/en/substreams/developing/sinks/sps/tutorial.mdx rename to website/pages/en/sps/tutorial.mdx diff --git a/website/pages/en/substreams/developing/sinks/_meta.js b/website/pages/en/substreams/developing/sinks/_meta.js index 9b2adb79687e..5facd5d582f5 100644 --- a/website/pages/en/substreams/developing/sinks/_meta.js +++ b/website/pages/en/substreams/developing/sinks/_meta.js @@ -1,4 +1,3 @@ export default { sinks: 'Official Sinks', - sps: 'Substreams-Powered Subgraphs', } diff --git a/website/pages/en/substreams/developing/sinks/sps/introduction.mdx b/website/pages/en/substreams/developing/sinks/sps/introduction.mdx deleted file mode 100644 index 847283da9fd1..000000000000 --- a/website/pages/en/substreams/developing/sinks/sps/introduction.mdx +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Introduction to Substreams-Powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: - -- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) -- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) -- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) -- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) -- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) From b3ec6ed8651f70b461e9546e882e7193eacabce0 Mon Sep 17 00:00:00 2001 From: Idalith Bustos Date: Thu, 23 Jan 2025 11:33:40 -0800 Subject: [PATCH 07/20] Updating copy & some links --- website/pages/en/sps/introduction.mdx | 6 ++--- website/pages/en/sps/sps-faq.mdx | 10 ++++--- website/pages/en/sps/triggers.mdx | 18 ++++++++++--- website/pages/en/sps/tutorial.mdx | 38 ++++++++++++++++++--------- 4 files changed, 49 insertions(+), 23 deletions(-) diff --git a/website/pages/en/sps/introduction.mdx b/website/pages/en/sps/introduction.mdx index 427576249d79..e26db72ad5d4 100644 --- a/website/pages/en/sps/introduction.mdx +++ b/website/pages/en/sps/introduction.mdx @@ -2,13 +2,13 @@ title: Introduction to Substreams-Powered Subgraphs --- -Boost your subgraph’s efficiency and scalability by using Substreams to stream pre-indexed blockchain data. +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. ## Overview Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. -## Specifics +### Specifics There are two methods of enabling this technology: @@ -18,7 +18,7 @@ There are two methods of enabling this technology: You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. -## Additional Resources +### Additional Resources Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: diff --git a/website/pages/en/sps/sps-faq.mdx b/website/pages/en/sps/sps-faq.mdx index 18248fc069df..8e553abfff21 100644 --- a/website/pages/en/sps/sps-faq.mdx +++ b/website/pages/en/sps/sps-faq.mdx @@ -4,15 +4,17 @@ title: Substreams-Powered Subgraphs FAQ ## What are Substreams? -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. ## What are Substreams-powered subgraphs? -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. ## How are Substreams-powered subgraphs different from subgraphs? diff --git a/website/pages/en/sps/triggers.mdx b/website/pages/en/sps/triggers.mdx index a923fe40ec78..137512f8baa7 100644 --- a/website/pages/en/sps/triggers.mdx +++ b/website/pages/en/sps/triggers.mdx @@ -2,9 +2,15 @@ title: Substreams Triggers --- -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. +Use Custom Triggers and enable the full use GraphQL. -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. @@ -28,10 +34,14 @@ export function handleTransactions(bytes: Uint8Array): void { } ``` -Here's what you’re seeing in the `mappings.ts` file: +Here's what you're seeing in the `mappings.ts` file: 1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object 2. Looping over the transactions 3. Create a new subgraph entity for every transaction -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/en/sps/tutorial.mdx b/website/pages/en/sps/tutorial.mdx index 4e84983a944d..dbdcf746fc1d 100644 --- a/website/pages/en/sps/tutorial.mdx +++ b/website/pages/en/sps/tutorial.mdx @@ -2,16 +2,20 @@ title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' --- -## Prerequisites +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites Before starting, make sure to: - Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. - Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. -## Step 1: Initialize Your Project - - +### Step 1: Initialize Your Project 1. Open your Dev Container and run the following command to initialize your project: @@ -46,7 +50,7 @@ params: # Modify the param fields to meet your needs map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE ``` -## Step 2: Generate the Subgraph Manifest +### Step 2: Generate the Subgraph Manifest Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: @@ -73,9 +77,11 @@ dataSources: handler: handleTriggers ``` -## Step 3: Define Entities in `schema.graphql` +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: +Here is an example: ```graphql type MyTransfer @entity { @@ -89,9 +95,11 @@ type MyTransfer @entity { This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. -## Step 4: Handle Substreams Data in `mappings.ts` +### Step 4: Handle Substreams Data in `mappings.ts` -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: ```ts import { Protobuf } from 'as-proto/assembly' @@ -122,7 +130,7 @@ export function handleTriggers(bytes: Uint8Array): void { } ``` -## Step 5: Generate Protobuf Files +### Step 5: Generate Protobuf Files To generate Protobuf objects in AssemblyScript, run the following command: @@ -132,8 +140,14 @@ npm run protogen This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. -## Conclusion +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. +### Additional Resources For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). From 83e3d156dbd40ac17a8ac9bff542474ba11bf03d Mon Sep 17 00:00:00 2001 From: Idalith Bustos Date: Thu, 23 Jan 2025 11:37:25 -0800 Subject: [PATCH 08/20] adjusting for all languages --- website/pages/ar/sps/_meta.js | 5 + website/pages/ar/sps/introduction.mdx | 29 +++ .../{sw/substreams => ar}/sps/sps-faq.mdx | 12 +- .../ar/{substreams => }/sps/triggers.mdx | 20 +- .../{de/substreams => ar}/sps/tutorial.mdx | 39 ++- .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/ar/substreams/developing/_meta.js | 5 + .../ar/substreams/developing/devcontainer.mdx | 47 ++++ .../ar/substreams/developing/sinks/_meta.js | 5 + .../ar/substreams/developing/sinks/sinks.mdx | 51 ++++ .../ar/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/ar/substreams/pubsubstreams.mdx | 52 ++++ website/pages/ar/substreams/sps/_meta.js | 5 - .../pages/ar/substreams/sps/introduction.mdx | 19 -- website/pages/ar/substreams/sps/sps-faq.mdx | 93 ------- website/pages/cs/sps/_meta.js | 5 + website/pages/cs/sps/introduction.mdx | 29 +++ .../{es/substreams => cs}/sps/sps-faq.mdx | 16 +- .../{de/substreams => cs}/sps/triggers.mdx | 20 +- .../{ar/substreams => cs}/sps/tutorial.mdx | 39 ++- .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/cs/substreams/developing/_meta.js | 5 + .../cs/substreams/developing/devcontainer.mdx | 47 ++++ .../cs/substreams/developing/sinks/_meta.js | 5 + .../cs/substreams/developing/sinks/sinks.mdx | 51 ++++ .../cs/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/cs/substreams/pubsubstreams.mdx | 52 ++++ website/pages/cs/substreams/sps/_meta.js | 5 - .../pages/cs/substreams/sps/introduction.mdx | 19 -- website/pages/cs/substreams/sps/sps-faq.mdx | 93 ------- website/pages/de/sps/_meta.js | 5 + website/pages/de/sps/introduction.mdx | 29 +++ .../{ko/substreams => de}/sps/sps-faq.mdx | 16 +- .../{es/substreams => de}/sps/triggers.mdx | 20 +- .../{es/substreams => de}/sps/tutorial.mdx | 39 ++- .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/de/substreams/developing/_meta.js | 5 + .../de/substreams/developing/devcontainer.mdx | 47 ++++ .../de/substreams/developing/sinks/_meta.js | 5 + .../de/substreams/developing/sinks/sinks.mdx | 51 ++++ .../de/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/de/substreams/pubsubstreams.mdx | 52 ++++ website/pages/de/substreams/sps/_meta.js | 5 - .../pages/de/substreams/sps/introduction.mdx | 19 -- website/pages/de/substreams/sps/sps-faq.mdx | 93 ------- website/pages/es/sps/_meta.js | 5 + website/pages/es/sps/introduction.mdx | 29 +++ .../{it/substreams => es}/sps/sps-faq.mdx | 16 +- .../{cs/substreams => es}/sps/triggers.mdx | 20 +- .../{cs/substreams => es}/sps/tutorial.mdx | 39 ++- .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/es/substreams/developing/_meta.js | 5 + .../es/substreams/developing/devcontainer.mdx | 47 ++++ .../es/substreams/developing/sinks/_meta.js | 5 + .../es/substreams/developing/sinks/sinks.mdx | 51 ++++ .../es/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/es/substreams/pubsubstreams.mdx | 52 ++++ website/pages/es/substreams/sps/_meta.js | 5 - .../pages/es/substreams/sps/introduction.mdx | 19 -- website/pages/fr/sps/_meta.js | 5 + website/pages/fr/sps/introduction.mdx | 29 +++ website/pages/fr/sps/sps-faq.mdx | 95 ++++++++ website/pages/fr/sps/triggers.mdx | 47 ++++ website/pages/fr/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/fr/substreams/developing/_meta.js | 5 + .../fr/substreams/developing/devcontainer.mdx | 47 ++++ .../fr/substreams/developing/sinks/_meta.js | 5 + .../fr/substreams/developing/sinks/sinks.mdx | 51 ++++ .../fr/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/fr/substreams/pubsubstreams.mdx | 52 ++++ website/pages/fr/substreams/sps/_meta.js | 5 - .../pages/fr/substreams/sps/introduction.mdx | 19 -- website/pages/fr/substreams/sps/sps-faq.mdx | 93 ------- website/pages/fr/substreams/sps/triggers.mdx | 37 --- website/pages/fr/substreams/sps/tutorial.mdx | 140 ----------- website/pages/hi/sps/_meta.js | 5 + website/pages/hi/sps/introduction.mdx | 29 +++ website/pages/hi/sps/sps-faq.mdx | 95 ++++++++ website/pages/hi/sps/triggers.mdx | 47 ++++ website/pages/hi/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/hi/substreams/developing/_meta.js | 5 + .../hi/substreams/developing/devcontainer.mdx | 47 ++++ .../hi/substreams/developing/sinks/_meta.js | 5 + .../hi/substreams/developing/sinks/sinks.mdx | 51 ++++ .../hi/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/hi/substreams/pubsubstreams.mdx | 52 ++++ website/pages/hi/substreams/sps/_meta.js | 5 - .../pages/hi/substreams/sps/introduction.mdx | 19 -- website/pages/hi/substreams/sps/sps-faq.mdx | 93 ------- website/pages/hi/substreams/sps/triggers.mdx | 37 --- website/pages/hi/substreams/sps/tutorial.mdx | 140 ----------- website/pages/it/sps/_meta.js | 5 + website/pages/it/sps/introduction.mdx | 29 +++ website/pages/it/sps/sps-faq.mdx | 95 ++++++++ website/pages/it/sps/triggers.mdx | 47 ++++ website/pages/it/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/it/substreams/developing/_meta.js | 5 + .../it/substreams/developing/devcontainer.mdx | 47 ++++ .../it/substreams/developing/sinks/_meta.js | 5 + .../it/substreams/developing/sinks/sinks.mdx | 51 ++++ .../it/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/it/substreams/pubsubstreams.mdx | 52 ++++ website/pages/it/substreams/sps/_meta.js | 5 - .../pages/it/substreams/sps/introduction.mdx | 19 -- website/pages/it/substreams/sps/triggers.mdx | 37 --- website/pages/it/substreams/sps/tutorial.mdx | 140 ----------- website/pages/ja/sps/_meta.js | 5 + website/pages/ja/sps/introduction.mdx | 29 +++ website/pages/ja/sps/sps-faq.mdx | 95 ++++++++ website/pages/ja/sps/triggers.mdx | 47 ++++ website/pages/ja/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 225 ----------------- .../pages/ja/substreams/developing/_meta.js | 5 + .../ja/substreams/developing/devcontainer.mdx | 47 ++++ .../ja/substreams/developing/sinks/_meta.js | 5 + .../ja/substreams/developing/sinks/sinks.mdx | 51 ++++ .../ja/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/ja/substreams/pubsubstreams.mdx | 52 ++++ website/pages/ja/substreams/sps/_meta.js | 5 - .../pages/ja/substreams/sps/introduction.mdx | 19 -- website/pages/ja/substreams/sps/sps-faq.mdx | 93 ------- website/pages/ja/substreams/sps/triggers.mdx | 37 --- website/pages/ja/substreams/sps/tutorial.mdx | 140 ----------- website/pages/ko/sps/_meta.js | 5 + website/pages/ko/sps/introduction.mdx | 29 +++ website/pages/ko/sps/sps-faq.mdx | 95 ++++++++ website/pages/ko/sps/triggers.mdx | 47 ++++ website/pages/ko/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/ko/substreams/developing/_meta.js | 5 + .../ko/substreams/developing/devcontainer.mdx | 47 ++++ .../ko/substreams/developing/sinks/_meta.js | 5 + .../ko/substreams/developing/sinks/sinks.mdx | 51 ++++ .../ko/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/ko/substreams/pubsubstreams.mdx | 52 ++++ website/pages/ko/substreams/sps/_meta.js | 5 - .../pages/ko/substreams/sps/introduction.mdx | 19 -- website/pages/ko/substreams/sps/triggers.mdx | 37 --- website/pages/ko/substreams/sps/tutorial.mdx | 140 ----------- website/pages/mr/sps/_meta.js | 5 + website/pages/mr/sps/introduction.mdx | 29 +++ website/pages/mr/sps/sps-faq.mdx | 95 ++++++++ website/pages/mr/sps/triggers.mdx | 47 ++++ website/pages/mr/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/mr/substreams/developing/_meta.js | 5 + .../mr/substreams/developing/devcontainer.mdx | 47 ++++ .../mr/substreams/developing/sinks/_meta.js | 5 + .../mr/substreams/developing/sinks/sinks.mdx | 51 ++++ .../mr/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/mr/substreams/pubsubstreams.mdx | 52 ++++ website/pages/mr/substreams/sps/_meta.js | 5 - .../pages/mr/substreams/sps/introduction.mdx | 19 -- website/pages/mr/substreams/sps/sps-faq.mdx | 93 ------- website/pages/mr/substreams/sps/triggers.mdx | 37 --- website/pages/mr/substreams/sps/tutorial.mdx | 140 ----------- website/pages/nl/sps/_meta.js | 5 + website/pages/nl/sps/introduction.mdx | 29 +++ website/pages/nl/sps/sps-faq.mdx | 95 ++++++++ website/pages/nl/sps/triggers.mdx | 47 ++++ website/pages/nl/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/nl/substreams/developing/_meta.js | 5 + .../nl/substreams/developing/devcontainer.mdx | 47 ++++ .../nl/substreams/developing/sinks/_meta.js | 5 + .../nl/substreams/developing/sinks/sinks.mdx | 51 ++++ .../nl/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/nl/substreams/pubsubstreams.mdx | 52 ++++ website/pages/nl/substreams/sps/_meta.js | 5 - .../pages/nl/substreams/sps/introduction.mdx | 19 -- website/pages/nl/substreams/sps/sps-faq.mdx | 93 ------- website/pages/nl/substreams/sps/triggers.mdx | 37 --- website/pages/nl/substreams/sps/tutorial.mdx | 140 ----------- website/pages/pl/sps/_meta.js | 5 + website/pages/pl/sps/introduction.mdx | 29 +++ website/pages/pl/sps/sps-faq.mdx | 95 ++++++++ website/pages/pl/sps/triggers.mdx | 47 ++++ website/pages/pl/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/pl/substreams/developing/_meta.js | 5 + .../pl/substreams/developing/devcontainer.mdx | 47 ++++ .../pl/substreams/developing/sinks/_meta.js | 5 + .../pl/substreams/developing/sinks/sinks.mdx | 51 ++++ .../pl/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/pl/substreams/pubsubstreams.mdx | 52 ++++ website/pages/pl/substreams/sps/_meta.js | 5 - .../pages/pl/substreams/sps/introduction.mdx | 19 -- website/pages/pl/substreams/sps/sps-faq.mdx | 93 ------- website/pages/pl/substreams/sps/triggers.mdx | 37 --- website/pages/pl/substreams/sps/tutorial.mdx | 140 ----------- website/pages/pt/sps/_meta.js | 5 + website/pages/pt/sps/introduction.mdx | 29 +++ website/pages/pt/sps/sps-faq.mdx | 95 ++++++++ website/pages/pt/sps/triggers.mdx | 47 ++++ website/pages/pt/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/pt/substreams/developing/_meta.js | 5 + .../pt/substreams/developing/devcontainer.mdx | 47 ++++ .../pt/substreams/developing/sinks/_meta.js | 5 + .../pt/substreams/developing/sinks/sinks.mdx | 51 ++++ .../pt/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/pt/substreams/pubsubstreams.mdx | 52 ++++ website/pages/pt/substreams/sps/_meta.js | 5 - .../pages/pt/substreams/sps/introduction.mdx | 19 -- website/pages/pt/substreams/sps/sps-faq.mdx | 93 ------- website/pages/pt/substreams/sps/triggers.mdx | 37 --- website/pages/pt/substreams/sps/tutorial.mdx | 140 ----------- website/pages/ro/sps/_meta.js | 5 + website/pages/ro/sps/introduction.mdx | 29 +++ website/pages/ro/sps/sps-faq.mdx | 95 ++++++++ website/pages/ro/sps/triggers.mdx | 47 ++++ website/pages/ro/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/ro/substreams/developing/_meta.js | 5 + .../ro/substreams/developing/devcontainer.mdx | 47 ++++ .../ro/substreams/developing/sinks/_meta.js | 5 + .../ro/substreams/developing/sinks/sinks.mdx | 51 ++++ .../ro/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/ro/substreams/pubsubstreams.mdx | 52 ++++ website/pages/ro/substreams/sps/_meta.js | 5 - .../pages/ro/substreams/sps/introduction.mdx | 19 -- website/pages/ro/substreams/sps/sps-faq.mdx | 93 ------- website/pages/ro/substreams/sps/triggers.mdx | 37 --- website/pages/ro/substreams/sps/tutorial.mdx | 140 ----------- website/pages/ru/sps/_meta.js | 5 + website/pages/ru/sps/introduction.mdx | 29 +++ website/pages/ru/sps/sps-faq.mdx | 95 ++++++++ website/pages/ru/sps/triggers.mdx | 47 ++++ website/pages/ru/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/ru/substreams/developing/_meta.js | 5 + .../ru/substreams/developing/devcontainer.mdx | 47 ++++ .../ru/substreams/developing/sinks/_meta.js | 5 + .../ru/substreams/developing/sinks/sinks.mdx | 51 ++++ .../ru/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/ru/substreams/pubsubstreams.mdx | 52 ++++ website/pages/ru/substreams/sps/_meta.js | 5 - .../pages/ru/substreams/sps/introduction.mdx | 19 -- website/pages/ru/substreams/sps/sps-faq.mdx | 93 ------- website/pages/ru/substreams/sps/triggers.mdx | 37 --- website/pages/ru/substreams/sps/tutorial.mdx | 140 ----------- website/pages/sv/sps/_meta.js | 5 + website/pages/sv/sps/introduction.mdx | 29 +++ website/pages/sv/sps/sps-faq.mdx | 95 ++++++++ website/pages/sv/sps/triggers.mdx | 47 ++++ website/pages/sv/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/sv/substreams/developing/_meta.js | 5 + .../sv/substreams/developing/devcontainer.mdx | 47 ++++ .../sv/substreams/developing/sinks/_meta.js | 5 + .../sv/substreams/developing/sinks/sinks.mdx | 51 ++++ .../sv/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/sv/substreams/pubsubstreams.mdx | 52 ++++ website/pages/sv/substreams/sps/_meta.js | 5 - .../pages/sv/substreams/sps/introduction.mdx | 19 -- website/pages/sv/substreams/sps/sps-faq.mdx | 93 ------- website/pages/sv/substreams/sps/triggers.mdx | 37 --- website/pages/sv/substreams/sps/tutorial.mdx | 140 ----------- website/pages/sw/sps/_meta.js | 5 + website/pages/sw/sps/introduction.mdx | 29 +++ website/pages/sw/sps/sps-faq.mdx | 95 ++++++++ website/pages/sw/sps/triggers.mdx | 47 ++++ website/pages/sw/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/sw/substreams/developing/_meta.js | 5 + .../sw/substreams/developing/devcontainer.mdx | 47 ++++ .../sw/substreams/developing/sinks/_meta.js | 5 + .../sw/substreams/developing/sinks/sinks.mdx | 51 ++++ .../sw/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/sw/substreams/introduction.mdx | 44 ++++ website/pages/sw/substreams/pubsubstreams.mdx | 52 ++++ website/pages/sw/substreams/sps/_meta.js | 5 - .../pages/sw/substreams/sps/introduction.mdx | 19 -- website/pages/sw/substreams/sps/triggers.mdx | 37 --- website/pages/sw/substreams/sps/tutorial.mdx | 140 ----------- website/pages/tr/sps/_meta.js | 5 + website/pages/tr/sps/introduction.mdx | 29 +++ website/pages/tr/sps/sps-faq.mdx | 95 ++++++++ website/pages/tr/sps/triggers.mdx | 47 ++++ website/pages/tr/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/tr/substreams/developing/_meta.js | 5 + .../tr/substreams/developing/devcontainer.mdx | 47 ++++ .../tr/substreams/developing/sinks/_meta.js | 5 + .../tr/substreams/developing/sinks/sinks.mdx | 51 ++++ .../tr/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/tr/substreams/pubsubstreams.mdx | 52 ++++ website/pages/tr/substreams/sps/_meta.js | 5 - .../pages/tr/substreams/sps/introduction.mdx | 19 -- website/pages/tr/substreams/sps/sps-faq.mdx | 93 ------- website/pages/tr/substreams/sps/triggers.mdx | 37 --- website/pages/tr/substreams/sps/tutorial.mdx | 140 ----------- website/pages/uk/sps/_meta.js | 5 + website/pages/uk/sps/introduction.mdx | 29 +++ website/pages/uk/sps/sps-faq.mdx | 95 ++++++++ website/pages/uk/sps/triggers.mdx | 47 ++++ website/pages/uk/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/uk/substreams/developing/_meta.js | 5 + .../uk/substreams/developing/devcontainer.mdx | 47 ++++ .../uk/substreams/developing/sinks/_meta.js | 5 + .../uk/substreams/developing/sinks/sinks.mdx | 51 ++++ .../uk/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/uk/substreams/pubsubstreams.mdx | 52 ++++ website/pages/uk/substreams/sps/_meta.js | 5 - .../pages/uk/substreams/sps/introduction.mdx | 19 -- website/pages/uk/substreams/sps/sps-faq.mdx | 93 ------- website/pages/uk/substreams/sps/triggers.mdx | 37 --- website/pages/uk/substreams/sps/tutorial.mdx | 140 ----------- website/pages/ur/sps/_meta.js | 5 + website/pages/ur/sps/introduction.mdx | 29 +++ website/pages/ur/sps/sps-faq.mdx | 95 ++++++++ website/pages/ur/sps/triggers.mdx | 47 ++++ website/pages/ur/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/ur/substreams/developing/_meta.js | 5 + .../ur/substreams/developing/devcontainer.mdx | 47 ++++ .../ur/substreams/developing/sinks/_meta.js | 5 + .../ur/substreams/developing/sinks/sinks.mdx | 51 ++++ .../ur/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/ur/substreams/pubsubstreams.mdx | 52 ++++ website/pages/ur/substreams/sps/_meta.js | 5 - .../pages/ur/substreams/sps/introduction.mdx | 19 -- website/pages/ur/substreams/sps/sps-faq.mdx | 93 ------- website/pages/ur/substreams/sps/triggers.mdx | 37 --- website/pages/ur/substreams/sps/tutorial.mdx | 140 ----------- website/pages/vi/sps/_meta.js | 5 + website/pages/vi/sps/introduction.mdx | 29 +++ website/pages/vi/sps/sps-faq.mdx | 95 ++++++++ website/pages/vi/sps/triggers.mdx | 47 ++++ website/pages/vi/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/vi/substreams/developing/_meta.js | 5 + .../vi/substreams/developing/devcontainer.mdx | 47 ++++ .../vi/substreams/developing/sinks/_meta.js | 5 + .../vi/substreams/developing/sinks/sinks.mdx | 51 ++++ .../vi/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/vi/substreams/pubsubstreams.mdx | 52 ++++ website/pages/vi/substreams/sps/_meta.js | 5 - .../pages/vi/substreams/sps/introduction.mdx | 19 -- website/pages/vi/substreams/sps/sps-faq.mdx | 93 ------- website/pages/vi/substreams/sps/triggers.mdx | 37 --- website/pages/vi/substreams/sps/tutorial.mdx | 140 ----------- website/pages/zh/sps/_meta.js | 5 + website/pages/zh/sps/introduction.mdx | 29 +++ website/pages/zh/sps/sps-faq.mdx | 95 ++++++++ website/pages/zh/sps/triggers.mdx | 47 ++++ website/pages/zh/sps/tutorial.mdx | 153 ++++++++++++ .../cookbook/substreams-powered-subgraphs.mdx | 226 ------------------ .../pages/zh/substreams/developing/_meta.js | 5 + .../zh/substreams/developing/devcontainer.mdx | 47 ++++ .../zh/substreams/developing/sinks/_meta.js | 5 + .../zh/substreams/developing/sinks/sinks.mdx | 51 ++++ .../zh/substreams/developing/solana/_meta.js | 5 + .../developing/solana/accountchanges.mdx | 62 +++++ .../substreams/developing/solana/solana.mdx | 15 ++ .../developing/solana/transactions.mdx | 60 +++++ .../substreams/getting-started-substreams.mdx | 41 ++++ website/pages/zh/substreams/pubsubstreams.mdx | 52 ++++ website/pages/zh/substreams/sps/_meta.js | 5 - .../pages/zh/substreams/sps/introduction.mdx | 19 -- website/pages/zh/substreams/sps/sps-faq.mdx | 93 ------- website/pages/zh/substreams/sps/triggers.mdx | 37 --- website/pages/zh/substreams/sps/tutorial.mdx | 140 ----------- 451 files changed, 13846 insertions(+), 10457 deletions(-) create mode 100644 website/pages/ar/sps/_meta.js create mode 100644 website/pages/ar/sps/introduction.mdx rename website/pages/{sw/substreams => ar}/sps/sps-faq.mdx (78%) rename website/pages/ar/{substreams => }/sps/triggers.mdx (57%) rename website/pages/{de/substreams => ar}/sps/tutorial.mdx (80%) delete mode 100644 website/pages/ar/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/ar/substreams/developing/_meta.js create mode 100644 website/pages/ar/substreams/developing/devcontainer.mdx create mode 100644 website/pages/ar/substreams/developing/sinks/_meta.js create mode 100644 website/pages/ar/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/ar/substreams/developing/solana/_meta.js create mode 100644 website/pages/ar/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/ar/substreams/developing/solana/solana.mdx create mode 100644 website/pages/ar/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/ar/substreams/getting-started-substreams.mdx create mode 100644 website/pages/ar/substreams/pubsubstreams.mdx delete mode 100644 website/pages/ar/substreams/sps/_meta.js delete mode 100644 website/pages/ar/substreams/sps/introduction.mdx delete mode 100644 website/pages/ar/substreams/sps/sps-faq.mdx create mode 100644 website/pages/cs/sps/_meta.js create mode 100644 website/pages/cs/sps/introduction.mdx rename website/pages/{es/substreams => cs}/sps/sps-faq.mdx (72%) rename website/pages/{de/substreams => cs}/sps/triggers.mdx (57%) rename website/pages/{ar/substreams => cs}/sps/tutorial.mdx (80%) delete mode 100644 website/pages/cs/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/cs/substreams/developing/_meta.js create mode 100644 website/pages/cs/substreams/developing/devcontainer.mdx create mode 100644 website/pages/cs/substreams/developing/sinks/_meta.js create mode 100644 website/pages/cs/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/cs/substreams/developing/solana/_meta.js create mode 100644 website/pages/cs/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/cs/substreams/developing/solana/solana.mdx create mode 100644 website/pages/cs/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/cs/substreams/getting-started-substreams.mdx create mode 100644 website/pages/cs/substreams/pubsubstreams.mdx delete mode 100644 website/pages/cs/substreams/sps/_meta.js delete mode 100644 website/pages/cs/substreams/sps/introduction.mdx delete mode 100644 website/pages/cs/substreams/sps/sps-faq.mdx create mode 100644 website/pages/de/sps/_meta.js create mode 100644 website/pages/de/sps/introduction.mdx rename website/pages/{ko/substreams => de}/sps/sps-faq.mdx (72%) rename website/pages/{es/substreams => de}/sps/triggers.mdx (57%) rename website/pages/{es/substreams => de}/sps/tutorial.mdx (80%) delete mode 100644 website/pages/de/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/de/substreams/developing/_meta.js create mode 100644 website/pages/de/substreams/developing/devcontainer.mdx create mode 100644 website/pages/de/substreams/developing/sinks/_meta.js create mode 100644 website/pages/de/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/de/substreams/developing/solana/_meta.js create mode 100644 website/pages/de/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/de/substreams/developing/solana/solana.mdx create mode 100644 website/pages/de/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/de/substreams/getting-started-substreams.mdx create mode 100644 website/pages/de/substreams/pubsubstreams.mdx delete mode 100644 website/pages/de/substreams/sps/_meta.js delete mode 100644 website/pages/de/substreams/sps/introduction.mdx delete mode 100644 website/pages/de/substreams/sps/sps-faq.mdx create mode 100644 website/pages/es/sps/_meta.js create mode 100644 website/pages/es/sps/introduction.mdx rename website/pages/{it/substreams => es}/sps/sps-faq.mdx (72%) rename website/pages/{cs/substreams => es}/sps/triggers.mdx (57%) rename website/pages/{cs/substreams => es}/sps/tutorial.mdx (80%) delete mode 100644 website/pages/es/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/es/substreams/developing/_meta.js create mode 100644 website/pages/es/substreams/developing/devcontainer.mdx create mode 100644 website/pages/es/substreams/developing/sinks/_meta.js create mode 100644 website/pages/es/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/es/substreams/developing/solana/_meta.js create mode 100644 website/pages/es/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/es/substreams/developing/solana/solana.mdx create mode 100644 website/pages/es/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/es/substreams/getting-started-substreams.mdx create mode 100644 website/pages/es/substreams/pubsubstreams.mdx delete mode 100644 website/pages/es/substreams/sps/_meta.js delete mode 100644 website/pages/es/substreams/sps/introduction.mdx create mode 100644 website/pages/fr/sps/_meta.js create mode 100644 website/pages/fr/sps/introduction.mdx create mode 100644 website/pages/fr/sps/sps-faq.mdx create mode 100644 website/pages/fr/sps/triggers.mdx create mode 100644 website/pages/fr/sps/tutorial.mdx delete mode 100644 website/pages/fr/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/fr/substreams/developing/_meta.js create mode 100644 website/pages/fr/substreams/developing/devcontainer.mdx create mode 100644 website/pages/fr/substreams/developing/sinks/_meta.js create mode 100644 website/pages/fr/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/fr/substreams/developing/solana/_meta.js create mode 100644 website/pages/fr/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/fr/substreams/developing/solana/solana.mdx create mode 100644 website/pages/fr/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/fr/substreams/getting-started-substreams.mdx create mode 100644 website/pages/fr/substreams/pubsubstreams.mdx delete mode 100644 website/pages/fr/substreams/sps/_meta.js delete mode 100644 website/pages/fr/substreams/sps/introduction.mdx delete mode 100644 website/pages/fr/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/fr/substreams/sps/triggers.mdx delete mode 100644 website/pages/fr/substreams/sps/tutorial.mdx create mode 100644 website/pages/hi/sps/_meta.js create mode 100644 website/pages/hi/sps/introduction.mdx create mode 100644 website/pages/hi/sps/sps-faq.mdx create mode 100644 website/pages/hi/sps/triggers.mdx create mode 100644 website/pages/hi/sps/tutorial.mdx delete mode 100644 website/pages/hi/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/hi/substreams/developing/_meta.js create mode 100644 website/pages/hi/substreams/developing/devcontainer.mdx create mode 100644 website/pages/hi/substreams/developing/sinks/_meta.js create mode 100644 website/pages/hi/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/hi/substreams/developing/solana/_meta.js create mode 100644 website/pages/hi/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/hi/substreams/developing/solana/solana.mdx create mode 100644 website/pages/hi/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/hi/substreams/getting-started-substreams.mdx create mode 100644 website/pages/hi/substreams/pubsubstreams.mdx delete mode 100644 website/pages/hi/substreams/sps/_meta.js delete mode 100644 website/pages/hi/substreams/sps/introduction.mdx delete mode 100644 website/pages/hi/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/hi/substreams/sps/triggers.mdx delete mode 100644 website/pages/hi/substreams/sps/tutorial.mdx create mode 100644 website/pages/it/sps/_meta.js create mode 100644 website/pages/it/sps/introduction.mdx create mode 100644 website/pages/it/sps/sps-faq.mdx create mode 100644 website/pages/it/sps/triggers.mdx create mode 100644 website/pages/it/sps/tutorial.mdx delete mode 100644 website/pages/it/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/it/substreams/developing/_meta.js create mode 100644 website/pages/it/substreams/developing/devcontainer.mdx create mode 100644 website/pages/it/substreams/developing/sinks/_meta.js create mode 100644 website/pages/it/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/it/substreams/developing/solana/_meta.js create mode 100644 website/pages/it/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/it/substreams/developing/solana/solana.mdx create mode 100644 website/pages/it/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/it/substreams/getting-started-substreams.mdx create mode 100644 website/pages/it/substreams/pubsubstreams.mdx delete mode 100644 website/pages/it/substreams/sps/_meta.js delete mode 100644 website/pages/it/substreams/sps/introduction.mdx delete mode 100644 website/pages/it/substreams/sps/triggers.mdx delete mode 100644 website/pages/it/substreams/sps/tutorial.mdx create mode 100644 website/pages/ja/sps/_meta.js create mode 100644 website/pages/ja/sps/introduction.mdx create mode 100644 website/pages/ja/sps/sps-faq.mdx create mode 100644 website/pages/ja/sps/triggers.mdx create mode 100644 website/pages/ja/sps/tutorial.mdx delete mode 100644 website/pages/ja/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/ja/substreams/developing/_meta.js create mode 100644 website/pages/ja/substreams/developing/devcontainer.mdx create mode 100644 website/pages/ja/substreams/developing/sinks/_meta.js create mode 100644 website/pages/ja/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/ja/substreams/developing/solana/_meta.js create mode 100644 website/pages/ja/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/ja/substreams/developing/solana/solana.mdx create mode 100644 website/pages/ja/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/ja/substreams/getting-started-substreams.mdx create mode 100644 website/pages/ja/substreams/pubsubstreams.mdx delete mode 100644 website/pages/ja/substreams/sps/_meta.js delete mode 100644 website/pages/ja/substreams/sps/introduction.mdx delete mode 100644 website/pages/ja/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/ja/substreams/sps/triggers.mdx delete mode 100644 website/pages/ja/substreams/sps/tutorial.mdx create mode 100644 website/pages/ko/sps/_meta.js create mode 100644 website/pages/ko/sps/introduction.mdx create mode 100644 website/pages/ko/sps/sps-faq.mdx create mode 100644 website/pages/ko/sps/triggers.mdx create mode 100644 website/pages/ko/sps/tutorial.mdx delete mode 100644 website/pages/ko/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/ko/substreams/developing/_meta.js create mode 100644 website/pages/ko/substreams/developing/devcontainer.mdx create mode 100644 website/pages/ko/substreams/developing/sinks/_meta.js create mode 100644 website/pages/ko/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/ko/substreams/developing/solana/_meta.js create mode 100644 website/pages/ko/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/ko/substreams/developing/solana/solana.mdx create mode 100644 website/pages/ko/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/ko/substreams/getting-started-substreams.mdx create mode 100644 website/pages/ko/substreams/pubsubstreams.mdx delete mode 100644 website/pages/ko/substreams/sps/_meta.js delete mode 100644 website/pages/ko/substreams/sps/introduction.mdx delete mode 100644 website/pages/ko/substreams/sps/triggers.mdx delete mode 100644 website/pages/ko/substreams/sps/tutorial.mdx create mode 100644 website/pages/mr/sps/_meta.js create mode 100644 website/pages/mr/sps/introduction.mdx create mode 100644 website/pages/mr/sps/sps-faq.mdx create mode 100644 website/pages/mr/sps/triggers.mdx create mode 100644 website/pages/mr/sps/tutorial.mdx delete mode 100644 website/pages/mr/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/mr/substreams/developing/_meta.js create mode 100644 website/pages/mr/substreams/developing/devcontainer.mdx create mode 100644 website/pages/mr/substreams/developing/sinks/_meta.js create mode 100644 website/pages/mr/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/mr/substreams/developing/solana/_meta.js create mode 100644 website/pages/mr/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/mr/substreams/developing/solana/solana.mdx create mode 100644 website/pages/mr/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/mr/substreams/getting-started-substreams.mdx create mode 100644 website/pages/mr/substreams/pubsubstreams.mdx delete mode 100644 website/pages/mr/substreams/sps/_meta.js delete mode 100644 website/pages/mr/substreams/sps/introduction.mdx delete mode 100644 website/pages/mr/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/mr/substreams/sps/triggers.mdx delete mode 100644 website/pages/mr/substreams/sps/tutorial.mdx create mode 100644 website/pages/nl/sps/_meta.js create mode 100644 website/pages/nl/sps/introduction.mdx create mode 100644 website/pages/nl/sps/sps-faq.mdx create mode 100644 website/pages/nl/sps/triggers.mdx create mode 100644 website/pages/nl/sps/tutorial.mdx delete mode 100644 website/pages/nl/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/nl/substreams/developing/_meta.js create mode 100644 website/pages/nl/substreams/developing/devcontainer.mdx create mode 100644 website/pages/nl/substreams/developing/sinks/_meta.js create mode 100644 website/pages/nl/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/nl/substreams/developing/solana/_meta.js create mode 100644 website/pages/nl/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/nl/substreams/developing/solana/solana.mdx create mode 100644 website/pages/nl/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/nl/substreams/getting-started-substreams.mdx create mode 100644 website/pages/nl/substreams/pubsubstreams.mdx delete mode 100644 website/pages/nl/substreams/sps/_meta.js delete mode 100644 website/pages/nl/substreams/sps/introduction.mdx delete mode 100644 website/pages/nl/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/nl/substreams/sps/triggers.mdx delete mode 100644 website/pages/nl/substreams/sps/tutorial.mdx create mode 100644 website/pages/pl/sps/_meta.js create mode 100644 website/pages/pl/sps/introduction.mdx create mode 100644 website/pages/pl/sps/sps-faq.mdx create mode 100644 website/pages/pl/sps/triggers.mdx create mode 100644 website/pages/pl/sps/tutorial.mdx delete mode 100644 website/pages/pl/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/pl/substreams/developing/_meta.js create mode 100644 website/pages/pl/substreams/developing/devcontainer.mdx create mode 100644 website/pages/pl/substreams/developing/sinks/_meta.js create mode 100644 website/pages/pl/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/pl/substreams/developing/solana/_meta.js create mode 100644 website/pages/pl/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/pl/substreams/developing/solana/solana.mdx create mode 100644 website/pages/pl/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/pl/substreams/getting-started-substreams.mdx create mode 100644 website/pages/pl/substreams/pubsubstreams.mdx delete mode 100644 website/pages/pl/substreams/sps/_meta.js delete mode 100644 website/pages/pl/substreams/sps/introduction.mdx delete mode 100644 website/pages/pl/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/pl/substreams/sps/triggers.mdx delete mode 100644 website/pages/pl/substreams/sps/tutorial.mdx create mode 100644 website/pages/pt/sps/_meta.js create mode 100644 website/pages/pt/sps/introduction.mdx create mode 100644 website/pages/pt/sps/sps-faq.mdx create mode 100644 website/pages/pt/sps/triggers.mdx create mode 100644 website/pages/pt/sps/tutorial.mdx delete mode 100644 website/pages/pt/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/pt/substreams/developing/_meta.js create mode 100644 website/pages/pt/substreams/developing/devcontainer.mdx create mode 100644 website/pages/pt/substreams/developing/sinks/_meta.js create mode 100644 website/pages/pt/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/pt/substreams/developing/solana/_meta.js create mode 100644 website/pages/pt/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/pt/substreams/developing/solana/solana.mdx create mode 100644 website/pages/pt/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/pt/substreams/getting-started-substreams.mdx create mode 100644 website/pages/pt/substreams/pubsubstreams.mdx delete mode 100644 website/pages/pt/substreams/sps/_meta.js delete mode 100644 website/pages/pt/substreams/sps/introduction.mdx delete mode 100644 website/pages/pt/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/pt/substreams/sps/triggers.mdx delete mode 100644 website/pages/pt/substreams/sps/tutorial.mdx create mode 100644 website/pages/ro/sps/_meta.js create mode 100644 website/pages/ro/sps/introduction.mdx create mode 100644 website/pages/ro/sps/sps-faq.mdx create mode 100644 website/pages/ro/sps/triggers.mdx create mode 100644 website/pages/ro/sps/tutorial.mdx delete mode 100644 website/pages/ro/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/ro/substreams/developing/_meta.js create mode 100644 website/pages/ro/substreams/developing/devcontainer.mdx create mode 100644 website/pages/ro/substreams/developing/sinks/_meta.js create mode 100644 website/pages/ro/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/ro/substreams/developing/solana/_meta.js create mode 100644 website/pages/ro/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/ro/substreams/developing/solana/solana.mdx create mode 100644 website/pages/ro/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/ro/substreams/getting-started-substreams.mdx create mode 100644 website/pages/ro/substreams/pubsubstreams.mdx delete mode 100644 website/pages/ro/substreams/sps/_meta.js delete mode 100644 website/pages/ro/substreams/sps/introduction.mdx delete mode 100644 website/pages/ro/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/ro/substreams/sps/triggers.mdx delete mode 100644 website/pages/ro/substreams/sps/tutorial.mdx create mode 100644 website/pages/ru/sps/_meta.js create mode 100644 website/pages/ru/sps/introduction.mdx create mode 100644 website/pages/ru/sps/sps-faq.mdx create mode 100644 website/pages/ru/sps/triggers.mdx create mode 100644 website/pages/ru/sps/tutorial.mdx delete mode 100644 website/pages/ru/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/ru/substreams/developing/_meta.js create mode 100644 website/pages/ru/substreams/developing/devcontainer.mdx create mode 100644 website/pages/ru/substreams/developing/sinks/_meta.js create mode 100644 website/pages/ru/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/ru/substreams/developing/solana/_meta.js create mode 100644 website/pages/ru/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/ru/substreams/developing/solana/solana.mdx create mode 100644 website/pages/ru/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/ru/substreams/getting-started-substreams.mdx create mode 100644 website/pages/ru/substreams/pubsubstreams.mdx delete mode 100644 website/pages/ru/substreams/sps/_meta.js delete mode 100644 website/pages/ru/substreams/sps/introduction.mdx delete mode 100644 website/pages/ru/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/ru/substreams/sps/triggers.mdx delete mode 100644 website/pages/ru/substreams/sps/tutorial.mdx create mode 100644 website/pages/sv/sps/_meta.js create mode 100644 website/pages/sv/sps/introduction.mdx create mode 100644 website/pages/sv/sps/sps-faq.mdx create mode 100644 website/pages/sv/sps/triggers.mdx create mode 100644 website/pages/sv/sps/tutorial.mdx delete mode 100644 website/pages/sv/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/sv/substreams/developing/_meta.js create mode 100644 website/pages/sv/substreams/developing/devcontainer.mdx create mode 100644 website/pages/sv/substreams/developing/sinks/_meta.js create mode 100644 website/pages/sv/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/sv/substreams/developing/solana/_meta.js create mode 100644 website/pages/sv/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/sv/substreams/developing/solana/solana.mdx create mode 100644 website/pages/sv/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/sv/substreams/getting-started-substreams.mdx create mode 100644 website/pages/sv/substreams/pubsubstreams.mdx delete mode 100644 website/pages/sv/substreams/sps/_meta.js delete mode 100644 website/pages/sv/substreams/sps/introduction.mdx delete mode 100644 website/pages/sv/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/sv/substreams/sps/triggers.mdx delete mode 100644 website/pages/sv/substreams/sps/tutorial.mdx create mode 100644 website/pages/sw/sps/_meta.js create mode 100644 website/pages/sw/sps/introduction.mdx create mode 100644 website/pages/sw/sps/sps-faq.mdx create mode 100644 website/pages/sw/sps/triggers.mdx create mode 100644 website/pages/sw/sps/tutorial.mdx delete mode 100644 website/pages/sw/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/sw/substreams/developing/_meta.js create mode 100644 website/pages/sw/substreams/developing/devcontainer.mdx create mode 100644 website/pages/sw/substreams/developing/sinks/_meta.js create mode 100644 website/pages/sw/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/sw/substreams/developing/solana/_meta.js create mode 100644 website/pages/sw/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/sw/substreams/developing/solana/solana.mdx create mode 100644 website/pages/sw/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/sw/substreams/getting-started-substreams.mdx create mode 100644 website/pages/sw/substreams/introduction.mdx create mode 100644 website/pages/sw/substreams/pubsubstreams.mdx delete mode 100644 website/pages/sw/substreams/sps/_meta.js delete mode 100644 website/pages/sw/substreams/sps/introduction.mdx delete mode 100644 website/pages/sw/substreams/sps/triggers.mdx delete mode 100644 website/pages/sw/substreams/sps/tutorial.mdx create mode 100644 website/pages/tr/sps/_meta.js create mode 100644 website/pages/tr/sps/introduction.mdx create mode 100644 website/pages/tr/sps/sps-faq.mdx create mode 100644 website/pages/tr/sps/triggers.mdx create mode 100644 website/pages/tr/sps/tutorial.mdx delete mode 100644 website/pages/tr/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/tr/substreams/developing/_meta.js create mode 100644 website/pages/tr/substreams/developing/devcontainer.mdx create mode 100644 website/pages/tr/substreams/developing/sinks/_meta.js create mode 100644 website/pages/tr/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/tr/substreams/developing/solana/_meta.js create mode 100644 website/pages/tr/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/tr/substreams/developing/solana/solana.mdx create mode 100644 website/pages/tr/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/tr/substreams/getting-started-substreams.mdx create mode 100644 website/pages/tr/substreams/pubsubstreams.mdx delete mode 100644 website/pages/tr/substreams/sps/_meta.js delete mode 100644 website/pages/tr/substreams/sps/introduction.mdx delete mode 100644 website/pages/tr/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/tr/substreams/sps/triggers.mdx delete mode 100644 website/pages/tr/substreams/sps/tutorial.mdx create mode 100644 website/pages/uk/sps/_meta.js create mode 100644 website/pages/uk/sps/introduction.mdx create mode 100644 website/pages/uk/sps/sps-faq.mdx create mode 100644 website/pages/uk/sps/triggers.mdx create mode 100644 website/pages/uk/sps/tutorial.mdx delete mode 100644 website/pages/uk/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/uk/substreams/developing/_meta.js create mode 100644 website/pages/uk/substreams/developing/devcontainer.mdx create mode 100644 website/pages/uk/substreams/developing/sinks/_meta.js create mode 100644 website/pages/uk/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/uk/substreams/developing/solana/_meta.js create mode 100644 website/pages/uk/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/uk/substreams/developing/solana/solana.mdx create mode 100644 website/pages/uk/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/uk/substreams/getting-started-substreams.mdx create mode 100644 website/pages/uk/substreams/pubsubstreams.mdx delete mode 100644 website/pages/uk/substreams/sps/_meta.js delete mode 100644 website/pages/uk/substreams/sps/introduction.mdx delete mode 100644 website/pages/uk/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/uk/substreams/sps/triggers.mdx delete mode 100644 website/pages/uk/substreams/sps/tutorial.mdx create mode 100644 website/pages/ur/sps/_meta.js create mode 100644 website/pages/ur/sps/introduction.mdx create mode 100644 website/pages/ur/sps/sps-faq.mdx create mode 100644 website/pages/ur/sps/triggers.mdx create mode 100644 website/pages/ur/sps/tutorial.mdx delete mode 100644 website/pages/ur/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/ur/substreams/developing/_meta.js create mode 100644 website/pages/ur/substreams/developing/devcontainer.mdx create mode 100644 website/pages/ur/substreams/developing/sinks/_meta.js create mode 100644 website/pages/ur/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/ur/substreams/developing/solana/_meta.js create mode 100644 website/pages/ur/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/ur/substreams/developing/solana/solana.mdx create mode 100644 website/pages/ur/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/ur/substreams/getting-started-substreams.mdx create mode 100644 website/pages/ur/substreams/pubsubstreams.mdx delete mode 100644 website/pages/ur/substreams/sps/_meta.js delete mode 100644 website/pages/ur/substreams/sps/introduction.mdx delete mode 100644 website/pages/ur/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/ur/substreams/sps/triggers.mdx delete mode 100644 website/pages/ur/substreams/sps/tutorial.mdx create mode 100644 website/pages/vi/sps/_meta.js create mode 100644 website/pages/vi/sps/introduction.mdx create mode 100644 website/pages/vi/sps/sps-faq.mdx create mode 100644 website/pages/vi/sps/triggers.mdx create mode 100644 website/pages/vi/sps/tutorial.mdx delete mode 100644 website/pages/vi/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/vi/substreams/developing/_meta.js create mode 100644 website/pages/vi/substreams/developing/devcontainer.mdx create mode 100644 website/pages/vi/substreams/developing/sinks/_meta.js create mode 100644 website/pages/vi/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/vi/substreams/developing/solana/_meta.js create mode 100644 website/pages/vi/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/vi/substreams/developing/solana/solana.mdx create mode 100644 website/pages/vi/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/vi/substreams/getting-started-substreams.mdx create mode 100644 website/pages/vi/substreams/pubsubstreams.mdx delete mode 100644 website/pages/vi/substreams/sps/_meta.js delete mode 100644 website/pages/vi/substreams/sps/introduction.mdx delete mode 100644 website/pages/vi/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/vi/substreams/sps/triggers.mdx delete mode 100644 website/pages/vi/substreams/sps/tutorial.mdx create mode 100644 website/pages/zh/sps/_meta.js create mode 100644 website/pages/zh/sps/introduction.mdx create mode 100644 website/pages/zh/sps/sps-faq.mdx create mode 100644 website/pages/zh/sps/triggers.mdx create mode 100644 website/pages/zh/sps/tutorial.mdx delete mode 100644 website/pages/zh/subgraphs/cookbook/substreams-powered-subgraphs.mdx create mode 100644 website/pages/zh/substreams/developing/_meta.js create mode 100644 website/pages/zh/substreams/developing/devcontainer.mdx create mode 100644 website/pages/zh/substreams/developing/sinks/_meta.js create mode 100644 website/pages/zh/substreams/developing/sinks/sinks.mdx create mode 100644 website/pages/zh/substreams/developing/solana/_meta.js create mode 100644 website/pages/zh/substreams/developing/solana/accountchanges.mdx create mode 100644 website/pages/zh/substreams/developing/solana/solana.mdx create mode 100644 website/pages/zh/substreams/developing/solana/transactions.mdx create mode 100644 website/pages/zh/substreams/getting-started-substreams.mdx create mode 100644 website/pages/zh/substreams/pubsubstreams.mdx delete mode 100644 website/pages/zh/substreams/sps/_meta.js delete mode 100644 website/pages/zh/substreams/sps/introduction.mdx delete mode 100644 website/pages/zh/substreams/sps/sps-faq.mdx delete mode 100644 website/pages/zh/substreams/sps/triggers.mdx delete mode 100644 website/pages/zh/substreams/sps/tutorial.mdx diff --git a/website/pages/ar/sps/_meta.js b/website/pages/ar/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/ar/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ar/sps/introduction.mdx b/website/pages/ar/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/ar/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/sw/substreams/sps/sps-faq.mdx b/website/pages/ar/sps/sps-faq.mdx similarity index 78% rename from website/pages/sw/substreams/sps/sps-faq.mdx rename to website/pages/ar/sps/sps-faq.mdx index f35d14cedae1..8e553abfff21 100644 --- a/website/pages/sw/substreams/sps/sps-faq.mdx +++ b/website/pages/ar/sps/sps-faq.mdx @@ -1,18 +1,20 @@ --- -title: Substreams-powered subgraphs FAQ +title: Substreams-Powered Subgraphs FAQ --- ## What are Substreams? -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. ## What are Substreams-powered subgraphs? -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. ## How are Substreams-powered subgraphs different from subgraphs? diff --git a/website/pages/ar/substreams/sps/triggers.mdx b/website/pages/ar/sps/triggers.mdx similarity index 57% rename from website/pages/ar/substreams/sps/triggers.mdx rename to website/pages/ar/sps/triggers.mdx index e5e510a6a7ad..137512f8baa7 100644 --- a/website/pages/ar/substreams/sps/triggers.mdx +++ b/website/pages/ar/sps/triggers.mdx @@ -2,15 +2,21 @@ title: Substreams Triggers --- -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. +Use Custom Triggers and enable the full use GraphQL. -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. ```tsx export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. if (transactions.length == 0) { log.info('No transactions found', []) return @@ -28,10 +34,14 @@ export function handleTransactions(bytes: Uint8Array): void { } ``` -Here's what you’re seeing in the `mappings.ts` file: +Here's what you're seeing in the `mappings.ts` file: 1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object 2. Looping over the transactions 3. Create a new subgraph entity for every transaction -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/de/substreams/sps/tutorial.mdx b/website/pages/ar/sps/tutorial.mdx similarity index 80% rename from website/pages/de/substreams/sps/tutorial.mdx rename to website/pages/ar/sps/tutorial.mdx index bb278b7f0eee..dbdcf746fc1d 100644 --- a/website/pages/de/substreams/sps/tutorial.mdx +++ b/website/pages/ar/sps/tutorial.mdx @@ -2,16 +2,20 @@ title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' --- -## Prerequisites +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites Before starting, make sure to: - Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. - Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. -## Step 1: Initialize Your Project - - +### Step 1: Initialize Your Project 1. Open your Dev Container and run the following command to initialize your project: @@ -20,7 +24,6 @@ Before starting, make sure to: ``` 2. Select the "minimal" project option. - 3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: ```yaml @@ -47,7 +50,7 @@ params: # Modify the param fields to meet your needs map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE ``` -## Step 2: Generate the Subgraph Manifest +### Step 2: Generate the Subgraph Manifest Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: @@ -74,9 +77,11 @@ dataSources: handler: handleTriggers ``` -## Step 3: Define Entities in `schema.graphql` +### Step 3: Define Entities in `schema.graphql` -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: ```graphql type MyTransfer @entity { @@ -90,9 +95,11 @@ type MyTransfer @entity { This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. -## Step 4: Handle Substreams Data in `mappings.ts` +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: ```ts import { Protobuf } from 'as-proto/assembly' @@ -123,7 +130,7 @@ export function handleTriggers(bytes: Uint8Array): void { } ``` -## Step 5: Generate Protobuf Files +### Step 5: Generate Protobuf Files To generate Protobuf objects in AssemblyScript, run the following command: @@ -133,8 +140,14 @@ npm run protogen This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. -## Conclusion +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. +### Additional Resources For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/ar/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/ar/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/ar/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/ar/substreams/developing/_meta.js b/website/pages/ar/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/ar/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ar/substreams/developing/devcontainer.mdx b/website/pages/ar/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/ar/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/ar/substreams/developing/sinks/_meta.js b/website/pages/ar/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/ar/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ar/substreams/developing/sinks/sinks.mdx b/website/pages/ar/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/ar/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/ar/substreams/developing/solana/_meta.js b/website/pages/ar/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/ar/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ar/substreams/developing/solana/accountchanges.mdx b/website/pages/ar/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/ar/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/ar/substreams/developing/solana/solana.mdx b/website/pages/ar/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/ar/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/ar/substreams/developing/solana/transactions.mdx b/website/pages/ar/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/ar/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/ar/substreams/getting-started-substreams.mdx b/website/pages/ar/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/ar/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/ar/substreams/pubsubstreams.mdx b/website/pages/ar/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/ar/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/ar/substreams/sps/_meta.js b/website/pages/ar/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/ar/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/ar/substreams/sps/introduction.mdx b/website/pages/ar/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/ar/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/ar/substreams/sps/sps-faq.mdx b/website/pages/ar/substreams/sps/sps-faq.mdx deleted file mode 100644 index 124d364afbc0..000000000000 --- a/website/pages/ar/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Substreams-powered subgraphs FAQ ---- - -## What are Substreams? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -اذهب إلى [وثائق سبستريمز](/substreams/introduction/) للتعرف على المزيد حول سبستريمز. - -## ما هي الغرافات الفرعية المدعومة بسبستريمز؟ - -[الغرافات الفرعية المدعومة بسبستريمز](/subgraphs/cookbook/substreams-powered-subgraphs/) تجمع بين قوة سبستريمز وقابلية الاستعلام للغرافات الفرعية. عند نشر غراف فرعي مدعوم بواسطة سبستريمز، يمكن أن تنتج البيانات التي تم إنتاجها بواسطة تحويلات سبستريمز، تغييرات في الكيانات (https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs)، والتي تكون متوافقة مع كيانات الغرافات الفرعية. - -إذا كنت على دراية بتطوير الغراف الفرعي، فإن الغرافات الفرعية المدعومة بواسطة سبستريمز يمكن استعلامها بنفس الطريقة كما لو أنها تم إنتاجها بواسطة طبقة تحويل لغة أسيمبلي اسكريبت، بالإضافة إلى جميع فوائد الغراف الفرعي، مثل توفير واجهة برمجة تطبيقات ديناميكية ومرنة للغة استعلام الغراف. - -## كيف تختلف الغرافات الفرعية التي تعمل بسبستريمز عن الغرافات الفرعية؟ - -الغرافات الفرعية تتكون من مصادر البيانات التي تحدد الأحداث على السلسلة وكيف ينبغي تحويل تلك الأحداث من خلال معالجات مكتوبة بـلغة أسمبلي اسكريبت. يتم معالجة هذه الأحداث بتسلسل، استناداً إلى ترتيب حدوث الأحداث على السلسلة. - -على نقيض ذلك، تحتوي الغرافات الفرعية المدعومة بسبستريمز على مصدر بيانات واحد يشير إلى حزمة سبستريمز، والتي يتم معالجتها بواسطة نقطة الغراف. تتيح سبستريمز الوصول إلى بيانات إضافية على السلسلة مقارنةً بالغرافات الفرعية التقليدية، ويمكن أيضاً للعمليات الموازية الضخمة أن توفر أوقات معالجة أسرع بكثير. - -## ما هي فوائد استخدام الغرافات الفرعية المدعومة بسبستريمز؟ - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## ماهي فوائد سبستريمز؟ - -There are many benefits to using Substreams, including: - -- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. - -- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). - -- التوجيه لأي مكان: يمكنك توجيه بياناتك لأي مكان ترغب فيه: بوستجريسكيو، مونغو دي بي، كافكا، الغرافات الفرعية، الملفات المسطحة، جداول جوجل. - -- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. - -- الوصول إلى بيانات إضافية غير متاحة كجزء من إجراء الإستدعاء عن بعد للترميز الكائني لجافاسكريبت - -- All the benefits of the Firehose. - -## What is the Firehose? - -تم تطوير فايرهوز بواسطة [StreamingFast] (https://www.streamingfast.io/) وهو طبقة استخراج بيانات سلاسل الكتل مصممة من الصفر لمعالجة كامل تاريخ سلاسل الكتل بسرعات لم يشهدها من قبل. يوفر نهجاً قائماً على الملفات وأولوية-التدفق، وهو مكون أساسي في مجموعة تقنيات ستريمنج فاست مفتوحة المصدر والأساس لسبستريمز. - -انتقل إلى [الوثائق](https://firehose.streamingfast.io/) لمعرفة المزيد حول فايرهوز. - -## What are the benefits of the Firehose? - -There are many benefits to using Firehose, including: - -- أقل تأخير وعدم الاستقصاء: بطريقة قائمة على أولوية-التدفق، تم تصميم نقاط فايرهوز للتسابق لدفع بيانات الكتلة أولاً. - -- Prevents downtimes: Designed from the ground up for High Availability. - -- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. - -- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. - -- يستفيد من الملفات المسطحة: يتم استخراج بيانات سلسلة الكتل إلى ملفات مسطحة، وهي أرخص وأكثر موارد الحوسبة تحسيناً. - -## أين يمكن للمطورين الوصول إلى مزيد من المعلومات حول الغرافات الفرعية المدعومة بسبستريمز و سبستريمز؟ - -The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. - -ستوضح لك [وثائق الغرافات الفرعية المدعومة بواسطة سبستريمز](/subgraphs/cookbook/substreams-powered-subgraphs/) كيفية تجميعها للنشر على الغراف. - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## What is the role of Rust modules in Substreams? - -تعتبر وحدات رست مكافئة لمعينات أسمبلي اسكريبت في الغرافات الفرعية. يتم ترجمتها إلى ويب أسيمبلي بنفس الطريقة، ولكن النموذج البرمجي يسمح بالتنفيذ الموازي. تحدد وحدات رست نوع التحويلات والتجميعات التي ترغب في تطبيقها على بيانات سلاسل الكتل الخام. - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## What makes Substreams composable? - -When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. - -على سبيل المثال، يمكن لأحمد بناء وحدة أسعار اسواق الصرف اللامركزية، ويمكن لإبراهيم استخدامها لبناء مجمِّع حجم للتوكن المهتم بها، ويمكن لآدم دمج أربع وحدات أسعار ديكس فردية لإنشاء مورد أسعار. سيقوم طلب واحد من سبستريمز بتجميع جميع هذه الوحدات الفردية، وربطها معًا لتقديم تدفق بيانات أكثر تطوراً ودقة. يمكن استخدام هذا التدفق لملءغراف فرعي ويمكن الاستعلام عنه من قبل المستخدمين. - -## كيف يمكنك إنشاء ونشر غراف فرعي مدعوم بسبستريمز؟ - -بعد [تعريف](/subgraphs/cookbook/substreams-powered-subgraphs/) الغراف الفرعي مدعوم بالسبستريمز، يمكنك استخدام واجهة سطر الأوامر للغراف لنشره في [استوديو الغراف الفرعي](https://thegraph.com/studio/). - -## أين يمكنني العثور على أمثلة على سبستريمز والغرافات الفرعية المدعومة بسبستريمز؟ - -يمكنك زيارة [جيت هب](https://github.com/pinax-network/awesome-substreams) للعثور على أمثلة للسبستريمز والغرافات الفرعية المدعومة بسبستريمز. - -## ماذا تعني السبستريمز والغرافات الفرعية المدعومة بسبستريمز بالنسبة لشبكة الغراف؟ - -إن التكامل مع سبستريمز والغرافات الفرعية المدعومة بسبستريمز واعدة بالعديد من الفوائد، بما في ذلك عمليات فهرسة عالية الأداء وقابلية أكبر للتركيبية من خلال استخدام وحدات المجتمع والبناء عليها. diff --git a/website/pages/cs/sps/_meta.js b/website/pages/cs/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/cs/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/cs/sps/introduction.mdx b/website/pages/cs/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/cs/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/es/substreams/sps/sps-faq.mdx b/website/pages/cs/sps/sps-faq.mdx similarity index 72% rename from website/pages/es/substreams/sps/sps-faq.mdx rename to website/pages/cs/sps/sps-faq.mdx index ec24f97300ae..8e553abfff21 100644 --- a/website/pages/es/substreams/sps/sps-faq.mdx +++ b/website/pages/cs/sps/sps-faq.mdx @@ -1,24 +1,26 @@ --- -title: Substreams-powered subgraphs FAQ +title: Substreams-Powered Subgraphs FAQ --- ## What are Substreams? -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. ## What are Substreams-powered subgraphs? -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. ## How are Substreams-powered subgraphs different from subgraphs? -Subgraphs are made up of datasources which specify on-chain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen on-chain. +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. -By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular on-chain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. ## What are the benefits of using Substreams-powered subgraphs? diff --git a/website/pages/de/substreams/sps/triggers.mdx b/website/pages/cs/sps/triggers.mdx similarity index 57% rename from website/pages/de/substreams/sps/triggers.mdx rename to website/pages/cs/sps/triggers.mdx index e5e510a6a7ad..137512f8baa7 100644 --- a/website/pages/de/substreams/sps/triggers.mdx +++ b/website/pages/cs/sps/triggers.mdx @@ -2,15 +2,21 @@ title: Substreams Triggers --- -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. +Use Custom Triggers and enable the full use GraphQL. -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. ```tsx export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. if (transactions.length == 0) { log.info('No transactions found', []) return @@ -28,10 +34,14 @@ export function handleTransactions(bytes: Uint8Array): void { } ``` -Here's what you’re seeing in the `mappings.ts` file: +Here's what you're seeing in the `mappings.ts` file: 1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object 2. Looping over the transactions 3. Create a new subgraph entity for every transaction -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/ar/substreams/sps/tutorial.mdx b/website/pages/cs/sps/tutorial.mdx similarity index 80% rename from website/pages/ar/substreams/sps/tutorial.mdx rename to website/pages/cs/sps/tutorial.mdx index 943e9898ed14..dbdcf746fc1d 100644 --- a/website/pages/ar/substreams/sps/tutorial.mdx +++ b/website/pages/cs/sps/tutorial.mdx @@ -2,16 +2,20 @@ title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' --- -## المتطلبات الأساسية +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites Before starting, make sure to: - Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. - Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. -## Step 1: Initialize Your Project - - +### Step 1: Initialize Your Project 1. Open your Dev Container and run the following command to initialize your project: @@ -20,7 +24,6 @@ Before starting, make sure to: ``` 2. Select the "minimal" project option. - 3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: ```yaml @@ -47,7 +50,7 @@ params: # Modify the param fields to meet your needs map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE ``` -## Step 2: Generate the Subgraph Manifest +### Step 2: Generate the Subgraph Manifest Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: @@ -74,9 +77,11 @@ dataSources: handler: handleTriggers ``` -## Step 3: Define Entities in `schema.graphql` +### Step 3: Define Entities in `schema.graphql` -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: ```graphql type MyTransfer @entity { @@ -90,9 +95,11 @@ type MyTransfer @entity { This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. -## Step 4: Handle Substreams Data in `mappings.ts` +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: ```ts import { Protobuf } from 'as-proto/assembly' @@ -123,7 +130,7 @@ export function handleTriggers(bytes: Uint8Array): void { } ``` -## Step 5: Generate Protobuf Files +### Step 5: Generate Protobuf Files To generate Protobuf objects in AssemblyScript, run the following command: @@ -133,8 +140,14 @@ npm run protogen This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. -## Conclusion +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. +### Additional Resources For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/cs/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/cs/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 348ddb6f4065..000000000000 --- a/website/pages/cs/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Podgrafy napájen substreamů ---- - -[Substreams](/substreams/introduction/) je nový framework pro zpracování blockchainových dat vyvinutý společností StreamingFast pro The Grafu síť. Moduly Substreams mohou vypisovat změny entit, které jsou kompatibilní s entitami Subgraph. Subgraph může takový modul Substreams používat jako zdroj dat, což vývojářům Subgraphu přináší rychlost indexování a další data Substreams. - -## Požadavky - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Získejte kuchařku - -> Tato kuchařka používá tento [Substreams-powered subgraph jako referenci](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Definování balíčku Substreams - -Balíček Substreams se skládá z typů (definovaných jako [Protocol Buffers](https://protobuf.dev/)), modulů (napsaných v jazyce Rust) a souboru `substreams.yaml`, který odkazuje na typy a určuje, jak se moduly spouštějí. [Navštivte dokumentaci Substreams, kde se dozvíte více o vývoji Substreams](/substreams/introduction/), a podívejte se na [awesome-substreams](https://github.com/pinax-network/awesome-substreams) a [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook), kde najdete další příklady. - -Dotyčný balíček Substreams detekuje nasazení kontraktů na Mainnet Ethereum a sleduje blok vytvoření a časové razítko všech nově nasazených kontraktů. K tomu je v souboru `/proto/example.proto` ([více informací o definování protokolových bufferů](https://protobuf.dev/programming-guides/proto3/#simple)) vyhrazen typ `Contract`: - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -Jádrem logiky balíčku Substreams je modul `map_contract` v souboru `lib.rs`, který zpracovává každý blok, filtruje volání Create, která nebyla vrácena, a vrací `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -Balíček Substreams může být použit podgrafem, pokud má modul, který vypisuje kompatibilní změny entit. Příklad balíčku Substreams má v `lib.rs` další modul `graph_out`, který vrací výstup `substreams_entity_change::pb::entity::EntityChanges`, který může zpracovat Graph Node. - -> Bedna `substreams_entity_change` má také speciální funkci `Tables` pro jednoduché generování změn entit ([dokumentace](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). Vygenerované změny entit musí být kompatibilní s entitami `schema.graphql` definovanými v `subgraph.graphql` příslušného podgrafu. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -Tyto typy a moduly jsou sdruženy v souboru `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -Celkový "tok" z bloku do `map_contract` a `graph_out` můžete zkontrolovat spuštěním `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -Chcete-li tento balíček Substreams připravit ke spotřebě podgrafem, musíte spustit následující příkazy: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> Tyto skripty jsou definovány v souboru `package.json`, pokud chcete porozumět základním příkazům substreamů - -Tím se vygeneruje soubor `spkg` na základě názvu a verze balíčku ze souboru `substreams.yaml`. Soubor `spkg` obsahuje všechny informace, které Grafu uzel potřebuje k požití tohoto balíčku Substreams. - -> Pokud aktualizujete balíček Substreams, může být v závislosti na provedených změnách nutné spustit některé nebo všechny výše uvedené příkazy, aby byl balíček `spkg` aktuální. - -## Definování podgrafu poháněný substreamů - -Subgrafy poháněné substreamy představují nový typ datového zdroje s názvem "substreams". Tyto subgrafy mohou mít pouze jeden datový zdroj. - -Tento zdroj dat musí specifikovat indexovanou síť, balíček Substreams (`spkg`) jako relativní umístění souboru a modul v rámci tohoto balíčku Substreams, který vytváří změny entit kompatibilní s podgrafem (v tomto případě `map_entity_changes` z výše uvedeného balíčku Substreams). Mapování je specifikováno, ale jednoduše identifikuje druh mapování ("substreams/graph-entities") a apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -Soubor `subgraph.yaml` také odkazuje na soubor se schématem. Požadavky na tento soubor se nemění, ale zadané entity musí být kompatibilní se změnami entit vytvořenými modulem Substreams, na který odkazuje soubor `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Vzhledem k výše uvedenému mohou vývojáři podgrafů použít rozhraní Graph CLI k nasazení tohoto podgrafu poháněného substreamy. - -> Subgrafy poháněné substreamy indexující hlavní síť Ethereum mohou být nasazeny do [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -Hotovo! Postavil(a) jste a nasadil(a) podgraf poháněný substreamy. - -## Obsluha podgrafů poháněných substreamy - -Aby bylo možné servírovat subgrafy napájené Substreams, musí být Graph Node nakonfigurován s poskytovatelem Substreams pro příslušnou síť a také s Firehose nebo RPC pro sledování hlavy řetězce. Tyto poskytovatele lze nakonfigurovat pomocí souboru `config.toml`: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/cs/substreams/developing/_meta.js b/website/pages/cs/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/cs/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/cs/substreams/developing/devcontainer.mdx b/website/pages/cs/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/cs/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/cs/substreams/developing/sinks/_meta.js b/website/pages/cs/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/cs/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/cs/substreams/developing/sinks/sinks.mdx b/website/pages/cs/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/cs/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/cs/substreams/developing/solana/_meta.js b/website/pages/cs/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/cs/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/cs/substreams/developing/solana/accountchanges.mdx b/website/pages/cs/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/cs/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/cs/substreams/developing/solana/solana.mdx b/website/pages/cs/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/cs/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/cs/substreams/developing/solana/transactions.mdx b/website/pages/cs/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/cs/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/cs/substreams/getting-started-substreams.mdx b/website/pages/cs/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/cs/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/cs/substreams/pubsubstreams.mdx b/website/pages/cs/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/cs/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/cs/substreams/sps/_meta.js b/website/pages/cs/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/cs/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/cs/substreams/sps/introduction.mdx b/website/pages/cs/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/cs/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/cs/substreams/sps/sps-faq.mdx b/website/pages/cs/substreams/sps/sps-faq.mdx deleted file mode 100644 index d6e28bf3296d..000000000000 --- a/website/pages/cs/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Podgrafy napájen substreamů ---- - -## Co jsou substreamu? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -Další informace o substreamu naleznete v [Dokumentace k substreamů](/substreams/introduction/). - -## Co jsou substreamu napájen podgrafy? - -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) kombinují sílu Substreams s možností dotazování na podgrafy. Při publikování Substreams-powered podgrafu mohou data vytvořená transformacemi Substreams [výstupní změny entit](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), které jsou kompatibilní s entitami podgrafu. - -Pokud jste již obeznámeni s vývojem podgrafů, pak vězte, že na podgrafy vytvořené pomocí Substreams se lze dotazovat stejně, jako kdyby byly vytvořeny transformační vrstvou AssemblyScript, se všemi výhodami Subgraphu, jako je poskytování dynamického a flexibilního GraphQL API. - -## Jak se liší substream, které jsou napájeny podgrafy, od podgrafů? - -Podgrafy jsou tvořeny datovými zdroji, které určují události v řetězci a způsob, jakým mají být tyto události transformovány prostřednictvím obslužných programů napsaných v jazyce Assemblyscript. Tyto události jsou zpracovávány postupně podle pořadí, v jakém k nim v řetězci dochází. - -Naproti tomu podgrafy napájené substreamy mají jediný zdroj dat, který odkazuje na balíček substreamů, který zpracovává uzel Graf. Substreamy mají ve srovnání s běžnými podgrafy přístup k dalším granulárním datům v řetězci a mohou také využívat výhod masivně paralelizovaného zpracování, což může znamenat mnohem rychlejší časy zpracování. - -## Jaké jsou výhody používání substreamu, které jsou založeny na podgraf? - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## Jaké jsou výhody Substreams? - -Používání ubstreams má mnoho výhod, mimo jiné: - -- Složitelný: Moduly Substreams můžete skládat na sebe jako kostky LEGO, stavět na komunitních moduly a dále vylepšovat veřejná data. - -- Vysoce výkonné indexování: Řádově rychlejší indexování prostřednictvím rozsáhlých klastrů paralelních operací (viz BigQuery). - -- Umyvadlo kdekoli: Data můžete ukládat kamkoli chcete: Vložte data do PostgreSQL, MongoDB, Kafka, podgrafy, ploché soubory, tabulky Google. - -- Programovatelné: Pomocí kódu můžete přizpůsobit extrakci, provádět agregace v čase transformace a modelovat výstup pro více zdrojů. - -- Přístup k dalším údajům, které nejsou k dispozici jako součást JSON RPC - -- Všechny výhody Firehose. - -## Co je Firehose? - -Firehose, vyvinutý společností [StreamingFast](https://www.streamingfast.io/), je vrstva pro extrakci dat z blockchainu, která byla od základu navržena tak, aby zpracovávala celou historii blockchainu dosud nevídanou rychlostí. Poskytuje přístup založený na souborech a streamování v první řadě a je klíčovou součástí sady open-source technologií StreamingFast a základem pro Substreams. - -Další informace o Firehose najdete v [dokumentaci](https://firehose.streamingfast.io/). - -## Jaké jsou výhody Firehose? - -Používání Firehose přináší mnoho výhod, včetně: - -- Nejnižší latence a žádné dotazování: Uzly Firehose jsou navrženy tak, aby se předháněly v odesílání blokových dat jako první. - -- Předchází výpadkům: Navrženo od základu pro vysokou dostupnost. - -- Nikdy nezmeškáte ani minutu: Proudový kurzor Firehose je navržen tak, aby si poradil s rozcestími a pokračoval tam, kde jste skončili, za jakýchkoli podmínek. - -- Nejbohatší datový model:  Nejlepší datový model, který zahrnuje změny zůstatku, celý strom volání, interní transakce, protokoly, změny v úložišti, náklady na plyn a další. - -- Využívá ploché soubory: Blockchain data jsou extrahována do plochých souborů, což je nejlevnější a nejoptimálnější dostupný výpočetní zdroj. - -## Kde mohou vývojáři získat více informací o substreamu, které jsou založeny na podgraf a substreamu? - -Dokumentace [Substreams](/substreams/introduction/) vás naučí, jak vytvářet moduly Substreams. - -Dokumentace [Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) vám ukáže, jak je zabalit pro nasazení na Grafu. - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## Jaká je role modulů Rust v Substreamu? - -Moduly Rust jsou ekvivalentem mapovačů AssemblyScript v podgraf. Jsou kompilovány do WASM podobným způsobem, ale programovací model umožňuje paralelní provádění. Definují druh transformací a agregací, které chcete aplikovat na surová data blockchainu. - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## Co dělá Substreamy složitelnými? - -Při použití substreamů probíhá kompozice na transformační vrstvě, což umožňuje opakované použití modulů uložených v mezipaměti. - -Jako příklad může Alice vytvořit cenový modul DEX, Bob jej může použít k vytvoření agregátoru objemu pro některé tokeny, které ho zajímají, a Lisa může zkombinovat čtyři jednotlivé cenové moduly DEX a vytvořit cenové orákulum. Jediný požadavek Substreams zabalí všechny moduly těchto jednotlivců, propojí je dohromady a nabídne mnohem sofistikovanější tok dat. Tento proud pak může být použit k naplnění podgrafu a může být dotazován spotřebiteli. - -## Jak můžete vytvořit a nasadit Substreams využívající podgraf? - -Po [definování](/subgraphs/cookbook/substreams-powered-subgraphs/) podgrafu s podporou substreamů jej můžete pomocí Graph CLI nasadit v [Subgraph Studio](https://thegraph.com/studio/). - -## Kde najdu příklady podgrafů Substreams a Substreams-powered? - -Příklady podgrafů Substreams a Substreams-powered najdete na [tomto repozitáři Github](https://github.com/pinax-network/awesome-substreams). - -## Co znamenají substreams a podgrafy napájené substreams pro síť grafů? - -Integrace slibuje mnoho výhod, včetně extrémně výkonného indexování a větší složitelnosti díky využití komunitních modulů a stavění na nich. diff --git a/website/pages/de/sps/_meta.js b/website/pages/de/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/de/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/de/sps/introduction.mdx b/website/pages/de/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/de/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/ko/substreams/sps/sps-faq.mdx b/website/pages/de/sps/sps-faq.mdx similarity index 72% rename from website/pages/ko/substreams/sps/sps-faq.mdx rename to website/pages/de/sps/sps-faq.mdx index ec24f97300ae..8e553abfff21 100644 --- a/website/pages/ko/substreams/sps/sps-faq.mdx +++ b/website/pages/de/sps/sps-faq.mdx @@ -1,24 +1,26 @@ --- -title: Substreams-powered subgraphs FAQ +title: Substreams-Powered Subgraphs FAQ --- ## What are Substreams? -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. ## What are Substreams-powered subgraphs? -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. ## How are Substreams-powered subgraphs different from subgraphs? -Subgraphs are made up of datasources which specify on-chain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen on-chain. +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. -By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular on-chain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. ## What are the benefits of using Substreams-powered subgraphs? diff --git a/website/pages/es/substreams/sps/triggers.mdx b/website/pages/de/sps/triggers.mdx similarity index 57% rename from website/pages/es/substreams/sps/triggers.mdx rename to website/pages/de/sps/triggers.mdx index e5e510a6a7ad..137512f8baa7 100644 --- a/website/pages/es/substreams/sps/triggers.mdx +++ b/website/pages/de/sps/triggers.mdx @@ -2,15 +2,21 @@ title: Substreams Triggers --- -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. +Use Custom Triggers and enable the full use GraphQL. -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. ```tsx export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. if (transactions.length == 0) { log.info('No transactions found', []) return @@ -28,10 +34,14 @@ export function handleTransactions(bytes: Uint8Array): void { } ``` -Here's what you’re seeing in the `mappings.ts` file: +Here's what you're seeing in the `mappings.ts` file: 1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object 2. Looping over the transactions 3. Create a new subgraph entity for every transaction -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/es/substreams/sps/tutorial.mdx b/website/pages/de/sps/tutorial.mdx similarity index 80% rename from website/pages/es/substreams/sps/tutorial.mdx rename to website/pages/de/sps/tutorial.mdx index f5b1d99ba473..dbdcf746fc1d 100644 --- a/website/pages/es/substreams/sps/tutorial.mdx +++ b/website/pages/de/sps/tutorial.mdx @@ -2,16 +2,20 @@ title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' --- -## Prerrequisitos +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites Before starting, make sure to: - Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. - Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. -## Step 1: Initialize Your Project - - +### Step 1: Initialize Your Project 1. Open your Dev Container and run the following command to initialize your project: @@ -20,7 +24,6 @@ Before starting, make sure to: ``` 2. Select the "minimal" project option. - 3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: ```yaml @@ -47,7 +50,7 @@ params: # Modify the param fields to meet your needs map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE ``` -## Step 2: Generate the Subgraph Manifest +### Step 2: Generate the Subgraph Manifest Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: @@ -74,9 +77,11 @@ dataSources: handler: handleTriggers ``` -## Step 3: Define Entities in `schema.graphql` +### Step 3: Define Entities in `schema.graphql` -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: ```graphql type MyTransfer @entity { @@ -90,9 +95,11 @@ type MyTransfer @entity { This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. -## Step 4: Handle Substreams Data in `mappings.ts` +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: ```ts import { Protobuf } from 'as-proto/assembly' @@ -123,7 +130,7 @@ export function handleTriggers(bytes: Uint8Array): void { } ``` -## Step 5: Generate Protobuf Files +### Step 5: Generate Protobuf Files To generate Protobuf objects in AssemblyScript, run the following command: @@ -133,8 +140,14 @@ npm run protogen This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. -## Conclusion +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. +### Additional Resources For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/de/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/de/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/de/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/de/substreams/developing/_meta.js b/website/pages/de/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/de/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/de/substreams/developing/devcontainer.mdx b/website/pages/de/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/de/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/de/substreams/developing/sinks/_meta.js b/website/pages/de/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/de/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/de/substreams/developing/sinks/sinks.mdx b/website/pages/de/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/de/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/de/substreams/developing/solana/_meta.js b/website/pages/de/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/de/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/de/substreams/developing/solana/accountchanges.mdx b/website/pages/de/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/de/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/de/substreams/developing/solana/solana.mdx b/website/pages/de/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/de/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/de/substreams/developing/solana/transactions.mdx b/website/pages/de/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/de/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/de/substreams/getting-started-substreams.mdx b/website/pages/de/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/de/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/de/substreams/pubsubstreams.mdx b/website/pages/de/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/de/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/de/substreams/sps/_meta.js b/website/pages/de/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/de/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/de/substreams/sps/introduction.mdx b/website/pages/de/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/de/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/de/substreams/sps/sps-faq.mdx b/website/pages/de/substreams/sps/sps-faq.mdx deleted file mode 100644 index ec24f97300ae..000000000000 --- a/website/pages/de/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Substreams-powered subgraphs FAQ ---- - -## What are Substreams? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. - -## What are Substreams-powered subgraphs? - -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. - -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. - -## How are Substreams-powered subgraphs different from subgraphs? - -Subgraphs are made up of datasources which specify on-chain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen on-chain. - -By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular on-chain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. - -## What are the benefits of using Substreams-powered subgraphs? - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## What are the benefits of Substreams? - -There are many benefits to using Substreams, including: - -- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. - -- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). - -- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. - -- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. - -- Access to additional data which is not available as part of the JSON RPC - -- All the benefits of the Firehose. - -## What is the Firehose? - -Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. - -Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. - -## What are the benefits of the Firehose? - -There are many benefits to using Firehose, including: - -- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. - -- Prevents downtimes: Designed from the ground up for High Availability. - -- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. - -- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. - -- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. - -## Where can developers access more information about Substreams-powered subgraphs and Substreams? - -The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. - -The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## What is the role of Rust modules in Substreams? - -Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## What makes Substreams composable? - -When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. - -As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. - -## How can you build and deploy a Substreams-powered Subgraph? - -After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). - -## Where can I find examples of Substreams and Substreams-powered subgraphs? - -You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. - -## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? - -The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/es/sps/_meta.js b/website/pages/es/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/es/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/es/sps/introduction.mdx b/website/pages/es/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/es/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/it/substreams/sps/sps-faq.mdx b/website/pages/es/sps/sps-faq.mdx similarity index 72% rename from website/pages/it/substreams/sps/sps-faq.mdx rename to website/pages/es/sps/sps-faq.mdx index ec24f97300ae..8e553abfff21 100644 --- a/website/pages/it/substreams/sps/sps-faq.mdx +++ b/website/pages/es/sps/sps-faq.mdx @@ -1,24 +1,26 @@ --- -title: Substreams-powered subgraphs FAQ +title: Substreams-Powered Subgraphs FAQ --- ## What are Substreams? -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. ## What are Substreams-powered subgraphs? -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. ## How are Substreams-powered subgraphs different from subgraphs? -Subgraphs are made up of datasources which specify on-chain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen on-chain. +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. -By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular on-chain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. ## What are the benefits of using Substreams-powered subgraphs? diff --git a/website/pages/cs/substreams/sps/triggers.mdx b/website/pages/es/sps/triggers.mdx similarity index 57% rename from website/pages/cs/substreams/sps/triggers.mdx rename to website/pages/es/sps/triggers.mdx index e5e510a6a7ad..137512f8baa7 100644 --- a/website/pages/cs/substreams/sps/triggers.mdx +++ b/website/pages/es/sps/triggers.mdx @@ -2,15 +2,21 @@ title: Substreams Triggers --- -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. +Use Custom Triggers and enable the full use GraphQL. -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. ```tsx export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. if (transactions.length == 0) { log.info('No transactions found', []) return @@ -28,10 +34,14 @@ export function handleTransactions(bytes: Uint8Array): void { } ``` -Here's what you’re seeing in the `mappings.ts` file: +Here's what you're seeing in the `mappings.ts` file: 1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object 2. Looping over the transactions 3. Create a new subgraph entity for every transaction -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/cs/substreams/sps/tutorial.mdx b/website/pages/es/sps/tutorial.mdx similarity index 80% rename from website/pages/cs/substreams/sps/tutorial.mdx rename to website/pages/es/sps/tutorial.mdx index 70dda12c61fd..dbdcf746fc1d 100644 --- a/website/pages/cs/substreams/sps/tutorial.mdx +++ b/website/pages/es/sps/tutorial.mdx @@ -2,16 +2,20 @@ title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' --- -## Požadavky +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites Before starting, make sure to: - Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. - Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. -## Step 1: Initialize Your Project - - +### Step 1: Initialize Your Project 1. Open your Dev Container and run the following command to initialize your project: @@ -20,7 +24,6 @@ Before starting, make sure to: ``` 2. Select the "minimal" project option. - 3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: ```yaml @@ -47,7 +50,7 @@ params: # Modify the param fields to meet your needs map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE ``` -## Step 2: Generate the Subgraph Manifest +### Step 2: Generate the Subgraph Manifest Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: @@ -74,9 +77,11 @@ dataSources: handler: handleTriggers ``` -## Step 3: Define Entities in `schema.graphql` +### Step 3: Define Entities in `schema.graphql` -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: ```graphql type MyTransfer @entity { @@ -90,9 +95,11 @@ type MyTransfer @entity { This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. -## Step 4: Handle Substreams Data in `mappings.ts` +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: ```ts import { Protobuf } from 'as-proto/assembly' @@ -123,7 +130,7 @@ export function handleTriggers(bytes: Uint8Array): void { } ``` -## Step 5: Generate Protobuf Files +### Step 5: Generate Protobuf Files To generate Protobuf objects in AssemblyScript, run the following command: @@ -133,8 +140,14 @@ npm run protogen This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. -## Závěr +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. +### Additional Resources For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/es/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/es/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/es/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/es/substreams/developing/_meta.js b/website/pages/es/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/es/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/es/substreams/developing/devcontainer.mdx b/website/pages/es/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/es/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/es/substreams/developing/sinks/_meta.js b/website/pages/es/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/es/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/es/substreams/developing/sinks/sinks.mdx b/website/pages/es/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/es/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/es/substreams/developing/solana/_meta.js b/website/pages/es/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/es/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/es/substreams/developing/solana/accountchanges.mdx b/website/pages/es/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/es/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/es/substreams/developing/solana/solana.mdx b/website/pages/es/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/es/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/es/substreams/developing/solana/transactions.mdx b/website/pages/es/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/es/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/es/substreams/getting-started-substreams.mdx b/website/pages/es/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/es/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/es/substreams/pubsubstreams.mdx b/website/pages/es/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/es/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/es/substreams/sps/_meta.js b/website/pages/es/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/es/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/es/substreams/sps/introduction.mdx b/website/pages/es/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/es/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/fr/sps/_meta.js b/website/pages/fr/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/fr/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/fr/sps/introduction.mdx b/website/pages/fr/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/fr/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/fr/sps/sps-faq.mdx b/website/pages/fr/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/fr/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/fr/sps/triggers.mdx b/website/pages/fr/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/fr/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/fr/sps/tutorial.mdx b/website/pages/fr/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/fr/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/fr/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/fr/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 76186d597c7a..000000000000 --- a/website/pages/fr/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Subgraphs alimentés par Substreams ---- - -[Substreams](/substreams/introduction/) est un nouveau framework de traitement des données blockchain, développé par StreamingFast pour The Graph Network. Un module de sous-flux peut générer des modifications d'entité, qui sont compatibles avec les entités Subgraph. Un subgraph peut utiliser un tel module Substreams comme source de données, apportant la vitesse d'indexation et les données supplémentaires des Substreams aux développeurs de subgraphs. - -## Exigences - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Obtenir le livre de cuisine - -> Ce guide utilise ce [subgraph alimenté par Substreams comme référence] (https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Définir un package Substreams - -Un paquet Substreams est composé de types (définis comme [Protocol Buffers](https://protobuf.dev/)), de modules (écrits en Rust) et d'un fichier `substreams.yaml` qui référence les types et spécifie comment les modules sont déclenchés. [Visitez la documentation Substreams pour en savoir plus sur le développement de Substreams](/substreams/introduction/), et consultez [awesome-substreams](https://github.com/pinax-network/awesome-substreams) et le [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) pour plus d'exemples. - -Le package Substreams en question détecte les déploiements de contrats sur Mainnet Ethereum, en suivant le bloc de création et l'horodatage de tous les contrats nouvellement déployés. Pour ce faire, il existe un type `Contract` dédié dans `/proto/example.proto` ([en savoir plus sur la définition des tampons de protocole](https://protobuf.dev/programming-guides/proto3/#simple)) : - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -La logique de base du paquet Substreams est un module `map_contract` dans `lib.rs`, qui traite chaque bloc, filtrant les appels Create qui n'ont pas été réversibles, et retournant des `Contrats` : - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -Un package Substreams peut être utilisé par un subgraph tant qu'il possède un module qui produit des changements d'entité compatibles. Le paquet Substreams de l'exemple a un module supplémentaire `graph_out` dans `lib.rs` qui renvoie une sortie `substreams_entity_change::pb::entity::EntityChanges`, qui peut être traitée par Graph Node. - -> Le crate `substreams_entity_change` a aussi une fonction `Tables` dédiée pour générer simplement des changements d'entités ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). Les changements d'entités générés doivent être compatibles avec les entités `schema.graphql` définies dans le `subgraph.graphql` du subgraph correspondant. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -Ces types et modules sont regroupés dans `substreams.yaml` : - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -Vous pouvez vérifier le « flux » global d'un bloc, vers « map_contract » et « graph_out » en exécutant « substreams graph » : - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -Pour préparer ce module Substreams à être utilisé par un subgraph, vous devez exécuter les commandes suivantes : - -```bash -yarn substreams:protogen # génère des types dans /src/pb -yarn substreams:build # construit les substreams -yarn substreams:package # empaquette les substreams dans un fichier .spkg - -# alternativement, yarn substreams:prepare appelle toutes les commandes ci-dessus -``` - -> Ces scripts sont définis dans le fichier `package.json` si vous voulez comprendre les commandes substreams sous-jacentes - -Cela génère un fichier `spkg` basé sur le nom et la version du paquet provenant de `substreams.yaml`. Le fichier `spkg` contient toutes les informations dont Graph Node a besoin pour ingérer ce paquet Substreams. - -> Si vous mettez à jour le module Substreams, en fonction des modifications apportées, vous devrez peut-être exécuter tout ou partie des commandes ci-dessus pour que le paquet `spkg` soit à jour. - -## Définition d'un subgraph alimenté par les courants de Substreams - -Les subgraphs alimentés par Substreams introduisent un nouveau type de source de données, "substreams". De tels subgraphs ne peuvent avoir qu'une seule source de données. - -Cette source de données doit spécifier le réseau indexé, le paquet Substreams (`spkg`) en tant qu'emplacement de fichier relatif, et le module au sein de ce paquet Substreams qui produit des changements d'entités compatibles avec le subgraph (dans ce cas, `map_entity_changes`, du paquet Substreams ci-dessus). Le mapping est spécifié, mais identifie simplement le type de mapping ("substreams/graph-entities") et l'apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -Le `subgraph.yaml` fait également référence à un fichier de schéma. Les exigences pour ce fichier sont inchangées, mais les entités spécifiées doivent être compatibles avec les changements d'entités produits par le module Substreams référencé dans le `subgraph.yaml`. - -```graphql -type Contrat @entity { - id: ID! - - "La date et l'heure de déploiement du contrat" - horodatage: String! - - "Le numéro de bloc du déploiement du contrat" - numéroDeBloc: BigInt! -} -``` - -Le `subgraph. yaml` fait également référence à un fichier de schéma. Les exigences pour ce fichier sont inchangées, mais les entités spécifiées doivent être compatibles avec les changements d'entités produits par le module Substreams référencé dans `subgraph. yaml`. - -> Les subgraphs alimentés par Substreams indexant le mainnet Ethereum peuvent être déployés sur le [Subgraph Studio] (https://thegraph.com/studio/). - -```bash -yarn install # installe graph-cli -yarn subgraph:build # construit le subgraph -yarn subgraph:deploy # déploie le subgraph -``` - -Voilà, c'est fait ! Vous avez construit et déployé un subgraph alimenté par Substreams. - -## Servir des subgraphs alimentés par Substreams - -Afin de servir des subgraphs alimentés par Substreams, Graph Node doit être configuré avec un fournisseur Substreams pour le réseau concerné, ainsi qu'un Firehose ou un RPC pour suivre la tête de chaîne. Ces fournisseurs peuvent être configurés via un fichier `config.toml` : - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "fournisseur-substreams-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exempletokenici" }}, - { label = "fournisseur-firehose-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exempletokenici" }}, -] -``` diff --git a/website/pages/fr/substreams/developing/_meta.js b/website/pages/fr/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/fr/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/fr/substreams/developing/devcontainer.mdx b/website/pages/fr/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/fr/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/fr/substreams/developing/sinks/_meta.js b/website/pages/fr/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/fr/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/fr/substreams/developing/sinks/sinks.mdx b/website/pages/fr/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/fr/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/fr/substreams/developing/solana/_meta.js b/website/pages/fr/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/fr/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/fr/substreams/developing/solana/accountchanges.mdx b/website/pages/fr/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/fr/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/fr/substreams/developing/solana/solana.mdx b/website/pages/fr/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/fr/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/fr/substreams/developing/solana/transactions.mdx b/website/pages/fr/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/fr/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/fr/substreams/getting-started-substreams.mdx b/website/pages/fr/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/fr/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/fr/substreams/pubsubstreams.mdx b/website/pages/fr/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/fr/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/fr/substreams/sps/_meta.js b/website/pages/fr/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/fr/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/fr/substreams/sps/introduction.mdx b/website/pages/fr/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/fr/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/fr/substreams/sps/sps-faq.mdx b/website/pages/fr/substreams/sps/sps-faq.mdx deleted file mode 100644 index 5f43a984b67b..000000000000 --- a/website/pages/fr/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: FAQ sur les subgraphs alimentés par les sous-flux ---- - -## Que sont les sous-flux ? - -Développé par [StreamingFast](https://www.streamingfast.io/), Substreams est un moteur de traitement extrêmement puissant capable de consommer des flux riches de données blockchain. Substreams vous permet de raffiner et de structurer les données blockchain pour une digestion rapide et fluide par les applications des utilisateurs finaux. Plus précisément, Substreams est un moteur agnostique à la blockchain, parallélisé et axé sur le streaming, servant de couche de transformation des données blockchain. Propulsé par [Firehose](https://firehose.streamingfast.io/), il permet aux développeurs d'écrire des modules Rust, de s'appuyer sur des modules communautaires, de fournir une indexation très performante, et de [diriger(sink)](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) leurs données vers n'importe quelle destination. - -Rendez-vous sur le site [Substreams Documentation](/substreams/introduction/) pour en savoir plus sur Substreams. - -## Qu'est-ce qu'un subgraph alimenté par des courants de fond ? - -Les [subgraphs alimentés par Substreams](/subgraphs/cookbook/substreams-powered-subgraphs/) combinent la puissance de Substreams avec la capacité d'interrogation des subgraphs. Lors de la publication d'un subgraph alimenté par Substreams, les données produites par les transformations Substreams peuvent [output entity changes] (https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), qui sont compatibles avec les entités du subgraph. - -Si vous êtes déjà familiarisé avec le développement de subgraphs, notez que les subgraphs alimentés par Substreams peuvent ensuite être interrogés, comme s'ils avaient été produits par la couche de transformation AssemblyScript, avec tous les avantages de Subgraph, comme la fourniture d'une API GraphQL dynamique et flexible. - -## En quoi les subgraphs alimentés par les courants secondaires sont-ils différents des subgraphs ? - -Les subgraphs sont constitués de sources de données qui spécifient les événements de la chaîne et la manière dont ces événements doivent être traités par des gestionnaires écrits en Assemblyscript. Ces événements sont traités de manière séquentielle, en fonction de l'ordre dans lequel ils se produisent dans la chaîne. - -En revanche, les subgraphs alimentés par des flux secondaires disposent d'une source de données unique référençant un paquet de flux secondaires, qui est traité par le nœud de graphe. Les subgraphs ont accès à des données granulaires supplémentaires sur la chaîne par rapport aux subgraphs conventionnels et peuvent également bénéficier d'un traitement massivement parallélisé, ce qui peut se traduire par des temps de traitement beaucoup plus rapides. - -## Quels sont les avantages de l'utilisation de subgraphs alimentés par des courants descendants ? - -Les subgraphs alimentés par Substreams combinent tous les avantages de Substreams avec la capacité d'intérrogation des subgraphs. Ils apportent une plus grande composabilité (la capacité des composants d'un système à être modifié et recombiné en une autre structure afin de répondre à des besoins précis.) et une indexation haute performance à The Graph. Ils permettent également de nouveaux cas d'utilisation de données; par exemple, une fois que vous avez construit votre subgraph alimenté par Substreams, vous pouvez réutiliser vos [modules Substreams](https://substreams.streamingfast.io/documentation/develop/manifest-modules) pour produire des sorties vers différents [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) tels que PostgreSQL, MongoDB et Kafka. - -## Quels sont les avantages de Substreams ? - -L'utilisation de Substreams présente de nombreux avantages, notamment: - -- Composable : Vous pouvez empiler les modules Substreams comme des blocs LEGO et construire des modules communautaires pour affiner les données publiques. - -- Indexation haute performance : Indexation plus rapide d'un ordre de grandeur grâce à des grappes d'opérations parallèles à grande échelle (comme BigQuery). - -- Sortez vos données n'importe où : Transférez vos données où vous le souhaitez : PostgreSQL, MongoDB, Kafka, subgraphs, fichiers plats, Google Sheets. - -- Programmable : Utilisez du code pour personnaliser l'extraction, effectuer des agrégations au moment de la transformation et modéliser vos résultats pour plusieurs puits. - -- Accès à des données supplémentaires qui ne sont pas disponibles dans le cadre de la RPC JSON - -- Tous les avantages du Firehose. - -## Tous les avantages du Firehose? - -Développé par [StreamingFast] (https://www.streamingfast.io/), le Firehose est une couche d'extraction de données de blockchain conçue à partir de zéro pour traiter l'historique complet des blockchains à des vitesses jusqu'alors inconnues . Obtenez une approche basée sur les fichiers et le streaming, il s'agit d'un composant essentiel de la suite de technologies open-source de StreamingFast et de la base de Substreams. - -Consultez la [documentation] (https://firehose.streamingfast.io/) pour en savoir plus sur le Firehose. - -## Quels sont les avantages du Firehose ? - -L'utilisation de Firehose présente de nombreux avantages, notamment: - -- Temps de latence le plus faible et pas d'interrogation : Les nœuds Firehose sont conçus pour faire la course afin de diffuser les données en bloc en premier, selon le principe "streaming-first". - -- Prévient les temps d'arrêt : Conçu dès le départ pour une haute disponibilité. - -- Ne manquez jamais le rythme : Le curseur du flux Firehose est conçu pour gérer les bifurcations et pour reprendre là où vous vous êtes arrêté dans n'importe quelle condition. - -- Modèle de données le plus riche :   Meilleur modèle de données qui inclut les changements de solde, l'arbre d'appel complet, les transactions internes, les journaux, les changements de stockage, les coûts du gaz, etc. - -- Exploite les fichiers plats : Les données de la blockchain sont extraites dans des fichiers plats, la ressource informatique la moins chère et la plus optimisée disponible. - -## Où les développeurs peuvent-ils trouver plus d'informations sur les subgraphs alimentés par Substreams et sur Substreams ? - -La [documentation Substreams](/substreams/introduction/) vous apprendra à construire des modules Substreams. - -La [documentation sur les subgraphs alimentés par des flux partiels] (/subgraphs/cookbook/substreams-powered-subgraphs/) vous montrera comment les emballer pour les déployer sur The Graph. - -Le [dernier outil Substreams Codegen ](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) vous permettra de lancer un projet Substreams sans aucun code. - -## Quel est le rôle des modules Rust dans Substreams ? - -Les modules Rust sont l'équivalent des mappeurs AssemblyScript dans les subgraphs. Ils sont compilés dans WASM de la même manière, mais le modèle de programmation permet une exécution parallèle. Ils définissent le type de transformations et d'agrégations que vous souhaitez appliquer aux données brutes de la blockchain. - -Consultez [ documentation des modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) pour plus de détails. - -## Qu'est-ce qui rend Substreams composable ? - -Lors de l'utilisation de Substreams, la composition a lieu au niveau de la couche de transformation, ce qui permet de réutiliser les modules mis en cache. - -Par exemple, Alice peut créer un module de prix DEX, Bob peut l'utiliser pour créer un agrégateur de volume pour certains jetons qui l'intéressent, et Lisa peut combiner quatre modules de prix DEX individuels pour créer un oracle de prix. Une seule requête Substreams regroupera tous ces modules individuels, les reliera entre eux, pour offrir un flux de données beaucoup plus raffiné. Ce flux peut ensuite être utilisé pour alimenter un subgraph et être interrogé par les consommateurs. - -## Comment pouvez-vous créer et déployer un Subgraph basé sur Substreams ? - -Après avoir [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) un Subgraph alimenté par Substreams, vous pouvez utiliser la CLI Graph pour le déployer dans [Subgraph Studio](https://thegraph.com/studio/). - -## Où puis-je trouver des exemples de subgraphs et de subgraphs alimentés par des substreams ? - -Vous pouvez visiter [ce repo Github] (https://github.com/pinax-network/awesome-substreams) pour trouver des exemples de Substreams et de subgraphs alimentés par Substreams. - -## Que signifient les subgraphs et les subgraphs alimentés par des substreams pour le réseau graph ? - -L'intégration promet de nombreux avantages, notamment une indexation extrêmement performante et une plus grande composabilité grâce à l'exploitation des modules de la communauté et à leur développement. diff --git a/website/pages/fr/substreams/sps/triggers.mdx b/website/pages/fr/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/fr/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/fr/substreams/sps/tutorial.mdx b/website/pages/fr/substreams/sps/tutorial.mdx deleted file mode 100644 index 92f5cb305599..000000000000 --- a/website/pages/fr/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Conditions préalables - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/hi/sps/_meta.js b/website/pages/hi/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/hi/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/hi/sps/introduction.mdx b/website/pages/hi/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/hi/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/hi/sps/sps-faq.mdx b/website/pages/hi/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/hi/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/hi/sps/triggers.mdx b/website/pages/hi/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/hi/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/hi/sps/tutorial.mdx b/website/pages/hi/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/hi/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/hi/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/hi/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/hi/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/hi/substreams/developing/_meta.js b/website/pages/hi/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/hi/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/hi/substreams/developing/devcontainer.mdx b/website/pages/hi/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/hi/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/hi/substreams/developing/sinks/_meta.js b/website/pages/hi/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/hi/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/hi/substreams/developing/sinks/sinks.mdx b/website/pages/hi/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/hi/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/hi/substreams/developing/solana/_meta.js b/website/pages/hi/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/hi/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/hi/substreams/developing/solana/accountchanges.mdx b/website/pages/hi/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/hi/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/hi/substreams/developing/solana/solana.mdx b/website/pages/hi/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/hi/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/hi/substreams/developing/solana/transactions.mdx b/website/pages/hi/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/hi/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/hi/substreams/getting-started-substreams.mdx b/website/pages/hi/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/hi/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/hi/substreams/pubsubstreams.mdx b/website/pages/hi/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/hi/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/hi/substreams/sps/_meta.js b/website/pages/hi/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/hi/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/hi/substreams/sps/introduction.mdx b/website/pages/hi/substreams/sps/introduction.mdx deleted file mode 100644 index f6ef302e9f53..000000000000 --- a/website/pages/hi/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Substreams-संचालित Subgraphs का परिचय ---- - -Substreams पैकेज (.spkg) का उपयोग करके, आपका subgraph पूर्व-सूचीबद्ध ब्लॉकचेन डेटा के एक स्ट्रीम तक पहुंच प्राप्त करता है। यह विशेष रूप से बड़े या जटिल ब्लॉकचेन नेटवर्क के साथ डेटा हैंडलिंग को अधिक कुशल और स्केलेबल बनाता है। - -इस तकनीक को सक्षम करने के दो तरीके हैं: - -Using Substreams triggers(/substreams/sps/triggers/): किसी भी Substreams मॉड्यूल से उपभोग करें, Protobuf मॉडल को एक subgraph हैंडलर के माध्यम से आयात करके और सभी लॉजिक को एक subgraph में स्थानांतरित करें। यह विधि subgraph संस्थाओं को सीधे subgraph में बनाती है। - -Entity Changes (https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out) का उपयोग करके: Substreams में अधिक लॉजिक लिखने से, आप सीधे graph-node में मॉड्यूल का आउटपुट प्राप्त कर सकते हैं। graph-node में, आप Substreams डेटा का उपयोग करके अपने उपग्रह संस्थाएं बना सकते हैं। - -यह वास्तव में इस पर निर्भर करता है कि आप अपनी लॉजिक को कहाँ रखते हैं, subgraph या Substreams में। ध्यान रखें कि यदि आपकी लॉजिक अधिकतर Substreams में है, तो इससे एक पैरेललाइज़्ड मॉडल का लाभ मिलता है, जबकि ट्रिगर्स graph-node में लाइनर रूप से उपभोग किए जाएंगे। - -नीचे दिए गए लिंक पर जाएं How-To गाइड्स के लिए जो आपको कोड-जनरेशन टूलिंग का उपयोग करके अपना पहला एंड-टू-एंड प्रोजेक्ट तेजी से बनाने में मदद करेंगे: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/hi/substreams/sps/sps-faq.mdx b/website/pages/hi/substreams/sps/sps-faq.mdx deleted file mode 100644 index ef6023edacc8..000000000000 --- a/website/pages/hi/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Substreams-powered subgraphs FAQ ---- - -## What are Substreams? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. - -## What are Substreams-powered subgraphs? - -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. - -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. - -## How are Substreams-powered subgraphs different from subgraphs? - -Subgraphs are made up of datasources which specify on-chain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen on-chain. - -By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular on-chain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. - -## What are the benefits of using Substreams-powered subgraphs? - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## What are the benefits of Substreams? - -There are many benefits to using Substreams, including: - -- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. - -- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). - -- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. - -- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. - -- Access to additional data which is not available as part of the JSON RPC - -- All the benefits of the Firehose. - -## What is the Firehose? - -Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. - -Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. - -## What are the benefits of the Firehose? - -There are many benefits to using Firehose, including: - -- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. - -- Prevents downtimes: Designed from the ground up for High Availability. - -- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. - -- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. - -- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. - -## Where can developers access more information about Substreams-powered subgraphs and Substreams? - -The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. - -The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. - -[नवीनतम Substreams Codegen टूल](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) आपको बिना किसी कोड के एक Substreams प्रोजेक्ट शुरू करने की अनुमति देगा। - -## What is the role of Rust modules in Substreams? - -Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## What makes Substreams composable? - -When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. - -As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. - -## How can you build and deploy a Substreams-powered Subgraph? - -After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). - -## Where can I find examples of Substreams and Substreams-powered subgraphs? - -You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. - -## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? - -The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/hi/substreams/sps/triggers.mdx b/website/pages/hi/substreams/sps/triggers.mdx deleted file mode 100644 index ca41d30e1f65..000000000000 --- a/website/pages/hi/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: सबस्ट्रीम्स ट्रिगर्स ---- - -कस्टम ट्रिगर्स आपको अपने subgraph मैपिंग फ़ाइल और इकाइयों (टेबल और फ़ील्ड के समान) में डेटा सीधे भेजने की अनुमति देते हैं, जो GraphQL परत का पूरा उपयोग करने में सक्षम बनाते हैं। अपने Substreams मॉड्यूल द्वारा उत्पन्न Protobuf परिभाषाओं को आयात करके, आप अपने subgraph के हैंडलर के भीतर इस डेटा को प्राप्त और प्रोसेस कर सकते हैं, जो subgraph ढांचे के भीतर कुशल और सुव्यवस्थित डेटा प्रबंधन सुनिश्चित करता है। - -> नोट: यदि आपने पहले से ऐसा नहीं किया है, तो अपने पहले प्रोजेक्ट को Development Container में स्कैफोल्ड करने के लिए यहाँ (/substreams/sps/introduction/) पाए जाने वाले How-To Guides में से एक पर जाएं। - -निम्नलिखित कोड यह दर्शाता है कि कैसे एक handleTransactions फ़ंक्शन को एक subgraph हैंडलर में परिभाषित किया जा सकता है। यह फ़ंक्शन कच्चे Substreams बाइट्स को एक पैरामीटर के रूप में प्राप्त करता है और उन्हें एक Transactions ऑब्जेक्ट में डिकोड करता है। प्रत्येक लेनदेन के लिए, एक नई subgraph एंटिटी बनाई जाती है। - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -यहां वह है जो आप mappings.ts फ़ाइल में देख रहे हैं: - -1. Substreams डेटा को जनरेट किए गए Transactions ऑब्जेक्ट में डिकोड किया जाता है, यह ऑब्जेक्ट किसी अन्य AssemblyScript ऑब्जेक्ट की तरह उपयोग किया जाता है। -2. लेनदेन पर लूप करना -3. प्रत्येक लेनदेन के लिए एक नया subgraph entity बनाएं - -ड्रैगर-आधारित एक उपग्राफ के विस्तृत उदाहरण के लिए, यहां क्लिक करें(/substreams/sps/tutorial/). diff --git a/website/pages/hi/substreams/sps/tutorial.mdx b/website/pages/hi/substreams/sps/tutorial.mdx deleted file mode 100644 index ae7347e22d72..000000000000 --- a/website/pages/hi/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'ट्यूटोरियल: Solana पर एक Substreams-शक्ति वाले Subgraph सेट करें' ---- - -## आवश्यक शर्तें - -'शुरू करने से पहले, सुनिश्चित करें कि:' - -- अपने विकास पर्यावरण को सेट अप करने के लिए Getting Started Guide(https://github.com/streamingfast/substreams-starter) को पूरा करें, एक Dev Container का उपयोग करके। -- The Graph और मूल ब्लॉकचेन अवधारणाओं जैसे कि लेनदेन और Protobufs से परिचित रहें। - -## चरण 1: अपने प्रोजेक्ट को प्रारंभ करें - - - -1. अपने Dev Container को खोलें और अपने प्रोजेक्ट को शुरू करने के लिए निम्नलिखित कमांड चलाएं: - - ```bash - substreams प्रारंभ करें - ``` - -2. "Minimal" प्रोजेक्ट विकल्प चुनें। - -3. substreams.yaml फ़ाइल की सामग्री को निम्नलिखित कॉन्फ़िगरेशन से बदलें, जो SPL टोकन प्रोग्राम आईडी पर Orca अकाउंट के लेनदेन को फ़िल्टर करता है: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## चरण 2: Subgraph Manifest उत्पन्न करें - -एक बार जब प्रोजेक्ट इनिशियलाइज़ हो जाए, Dev Container में निम्नलिखित कमांड चलाकर subgraph मैनिफेस्ट जेनरेट करें: - -```bash -'सबस्ट्रीम्स कोडजेन' subgraph -``` - -आप subgraph.yaml मैनिफेस्ट बनाएंगे जो डेटा स्रोत के रूप में Substreams पैकेज को इम्पोर्ट करता है: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## चरण 3: schema.graphql में संस्थाएँ परिभाषित करें - -अपने सबग्राफ एंटिटीज़ में सहेजने के लिए फ़ील्ड्स को परिभाषित करें, schema.graphql फ़ाइल को अपडेट करके। यहाँ एक उदाहरण है: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -यह स्कीमा एक MyTransfer एंटिटी को परिभाषित करता है जिसमें फ़ील्ड्स जैसे कि id, amount, source, designation, और signers शामिल हैं। - -## चरण 4: mappings.ts में Substreams डेटा को संभालें - -प्रोटोकॉल वस्तुओं के जनित होने के साथ, आप अब 'mappings.ts' फ़ाइल में डिकोडेड सबस्ट्रीम डेटा को संभाल सकते हैं, जो कि './src' निर्देशिका में पाई जाती है। नीचे दिया गया उदाहरण दिखाता है कि कैसे 'Orca' खाता आईडी से जुड़े गैर-व्युत्पन्न ट्रांसफर को सबग्राफ संस्थाओं में निकाला जा सकता है: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## चरण 5: Protobuf फ़ाइलें उत्पन्न करें - -AssemblyScript में Protobuf ऑब्जेक्ट बनाने के लिए, निम्नलिखित कमांड चलाएँ: - -```bash -npm चलाएँ protogen -``` - -यह कमांड Protobuf परिभाषाओं को AssemblyScript में परिवर्तित करता है, जिससे आप उन्हें हैंडलर में उपयोग कर सकते हैं। - -## निष्कर्ष - -आपने सफलतापूर्वक एक ट्रिगर-आधारित Substreams-शक्ति वाला subgraph स्थापित कर लिया है जो एक Solana SPL टोकन के लिए है। अब आप अपने विशिष्ट उपयोग के मामले के अनुसार अपने स्कीमा, मैपिंग और मॉड्यूल को और अनुकूलित कर सकते हैं। - -अधिक उन्नत अनुकूलन और ऑप्टिमाइजेशन के लिए, आधिकारिक Substreams documentation(https://substreams.streamingfast.io/tutorials/solana) देखें। diff --git a/website/pages/it/sps/_meta.js b/website/pages/it/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/it/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/it/sps/introduction.mdx b/website/pages/it/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/it/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/it/sps/sps-faq.mdx b/website/pages/it/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/it/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/it/sps/triggers.mdx b/website/pages/it/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/it/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/it/sps/tutorial.mdx b/website/pages/it/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/it/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/it/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/it/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/it/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/it/substreams/developing/_meta.js b/website/pages/it/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/it/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/it/substreams/developing/devcontainer.mdx b/website/pages/it/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/it/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/it/substreams/developing/sinks/_meta.js b/website/pages/it/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/it/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/it/substreams/developing/sinks/sinks.mdx b/website/pages/it/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/it/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/it/substreams/developing/solana/_meta.js b/website/pages/it/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/it/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/it/substreams/developing/solana/accountchanges.mdx b/website/pages/it/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/it/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/it/substreams/developing/solana/solana.mdx b/website/pages/it/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/it/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/it/substreams/developing/solana/transactions.mdx b/website/pages/it/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/it/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/it/substreams/getting-started-substreams.mdx b/website/pages/it/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/it/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/it/substreams/pubsubstreams.mdx b/website/pages/it/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/it/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/it/substreams/sps/_meta.js b/website/pages/it/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/it/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/it/substreams/sps/introduction.mdx b/website/pages/it/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/it/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/it/substreams/sps/triggers.mdx b/website/pages/it/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/it/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/it/substreams/sps/tutorial.mdx b/website/pages/it/substreams/sps/tutorial.mdx deleted file mode 100644 index bb278b7f0eee..000000000000 --- a/website/pages/it/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Prerequisites - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/ja/sps/_meta.js b/website/pages/ja/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/ja/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ja/sps/introduction.mdx b/website/pages/ja/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/ja/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/ja/sps/sps-faq.mdx b/website/pages/ja/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/ja/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/ja/sps/triggers.mdx b/website/pages/ja/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/ja/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/ja/sps/tutorial.mdx b/website/pages/ja/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/ja/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/ja/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/ja/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index df3533be5aaf..000000000000 --- a/website/pages/ja/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,225 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/)は、StreamingFastがThe Graph Networkのために開発した、ブロックチェーンのデータを処理するための新しいフレームワークである。サブストリームモジュールは、サブグラフエンティティと互換性のあるエンティティの変更を出力することができます。サブグラフはこのようなサブストリームモジュールをデータソースとして使用することができ、サブストリームのインデックス作成速度と追加データをサブグラフ開発者にもたらします。 - -## 要件 - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## 料理本を入手 - -> このクックブックでは、この [Substreams-powered subgraph を参考として](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph) を使用します。 - -``` -グラフ初期化 --from-example substreams-powered-subgraph -``` - -## サブストリームパッケージの定義 - -Substreamsパッケージは、型([プロトコルバッファ](https://protobuf.dev/)として定義される)、モジュール(Rustで記述される)、および型を参照し、モジュールがどのようにトリガーされるかを指定する`substreams.yaml`ファイルで構成されます。[サブストリームの開発についての詳細はサブストリームのドキュメントを参照](/substreams/introduction/)してください。また、[awesome-substreams](https://github.com/pinax-network/awesome-substreams)や[Substreams cookbook](https://github.com/pinax-network/substreams-cookbook)を参照してください。 - -問題の Substreams パッケージは、メインネット イーサリアム上のコントラクトのデプロイメントを検出し、新しくデプロイされたすべてのコントラクトの作成ブロックとタイムスタンプを追跡します。これを行うには、`/proto/example.proto` に専用の `Contract` タイプがあります ([プロトコル バッファーの定義の詳細](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -Substreams パッケージのコア ロジックは、`lib.rs` の `map_contract` モジュールです。これは、すべてのブロックを処理し、元に戻されなかった Create 呼び出しをフィルタリングして、`Contracts` を返します。 - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -``` - -Substreams パッケージは、互換性のあるエンティティの変更を出力するモジュールを持っている限り、サブグラフで使用できます。サンプルの Substreams パッケージには、「lib.rs」内に追加の「graph_out」モジュールがあり、グラフ ノードで処理できる「substreams_entity_change::pb::entity::EntityChanges」出力を返します。 - -> 「substreams_entity_change」クレートには、エンティティの変更を単純に生成するための専用の「Tables」関数もあります ([[documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html))。生成されたエンティティ変更は、対応するサブグラフの `subgraph.graphql` で定義された `schema.graphql` エンティティと互換性がある必要があります。 - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -これらの型とモジュールは `substreams.yaml` にまとめられています。 - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -`substreams chart` を実行することで、ブロックから `map_contract`、`graph_out` までの全体的な「フロー」を確認できます。 - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -この Substreams パッケージをサブグラフで使用できるように準備するには、次のコマンドを実行する必要があります。 - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> 基礎となるサブストリーム コマンドを理解したい場合は、これらのスクリプトは「package.json」ファイルで定義されます。 - -これにより、「substreams.yaml」のパッケージ名とバージョンに基づいて「spkg」ファイルが生成されます。 「spkg」ファイルには、グラフ ノードがこのサブストリーム パッケージを取り込むために必要なすべての情報が含まれています。 - -> Substreams パッケージを更新する場合、加えた変更に応じて、`spkg` を最新にするために上記のコマンドの一部またはすべてを実行する必要がある場合があります。 - -## サブストリームによって動作するサブグラフの定義 - -サブストリームによって動作するサブグラフは、新しい "substreams" というデータソースの kind を導入します。このようなサブグラフは、ただ1つのデータソースのみを持つことができます - -このデータ ソースは、インデックス付きネットワーク、相対的なファイルの場所としての Substreams パッケージ (`spkg`)、およびサブグラフ互換のエンティティ変更を生成するその Substreams パッケージ内のモジュール (この場合は、上記の Substreams パッケージからの `map_entity_changes`) を指定する必要があります。マッピングは指定されていますが、単にマッピングの種類 (「サブストリーム/グラフ エンティティ」) と apiVersion を識別するだけです。 - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -`subgraph.yaml` もスキーマ ファイルを参照します。このファイルの要件は変更されていませんが、指定されたエンティティは、`subgraph.yaml` で参照される Substreams モジュールによって生成されるエンティティの変更と互換性がある必要があります。 - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -上記を考慮すると、サブグラフ開発者は Graph CLI を使用して、このサブストリームを利用したサブグラフをデプロイできます。 - -> サブストリームを利用したサブグラフのインデックス作成メインネット Ethereum は、[Subgraph Studio](https://thegraph.com/studio/) にデプロイできます。 - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -それでおしまい!サブストリームを利用したサブグラフを構築してデプロイしました。 - -## サブストリームを利用したサブグラフの提供 - -サブストリームを利用したサブグラフを提供するには、チェーン ヘッドを追跡するための Firehose または RPC だけでなく、関連するネットワークのサブストリーム プロバイダーを使用してグラフ ノードを構成する必要があります。これらのプロバイダーは、「config.toml」ファイル経由で設定できます。 - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/ja/substreams/developing/_meta.js b/website/pages/ja/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/ja/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ja/substreams/developing/devcontainer.mdx b/website/pages/ja/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/ja/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/ja/substreams/developing/sinks/_meta.js b/website/pages/ja/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/ja/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ja/substreams/developing/sinks/sinks.mdx b/website/pages/ja/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/ja/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/ja/substreams/developing/solana/_meta.js b/website/pages/ja/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/ja/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ja/substreams/developing/solana/accountchanges.mdx b/website/pages/ja/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/ja/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/ja/substreams/developing/solana/solana.mdx b/website/pages/ja/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/ja/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/ja/substreams/developing/solana/transactions.mdx b/website/pages/ja/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/ja/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/ja/substreams/getting-started-substreams.mdx b/website/pages/ja/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/ja/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/ja/substreams/pubsubstreams.mdx b/website/pages/ja/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/ja/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/ja/substreams/sps/_meta.js b/website/pages/ja/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/ja/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/ja/substreams/sps/introduction.mdx b/website/pages/ja/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/ja/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/ja/substreams/sps/sps-faq.mdx b/website/pages/ja/substreams/sps/sps-faq.mdx deleted file mode 100644 index 642233729257..000000000000 --- a/website/pages/ja/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: サブストリームを利用したサブグラフに関するよくある質問 ---- - -## サブストリームとは何ですか? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -サブストリームの詳細については、[サブストリームのドキュメント](/substreams/introduction/) にアクセスしてください。 - -## サブストリームによって動作するサブグラフは何ですか? - -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) は、サブストリームの機能とサブグラフのクエリ可能性を組み合わせています。 サブストリームを利用したサブグラフを公開する場合、サブストリーム変換によって生成されたデータは、[エンティティの変更を出力](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change)できます。 /src/tables.rs)、サブグラフ エンティティと互換性があります。 - -すでにサブグラフ開発に​​精通している場合は、AssemblyScript 変換層によって生成されたかのように、サブストリームを利用したサブグラフをクエリできることに注意してください。動的で柔軟な GraphQL API の提供など、サブグラフのすべての利点が得られます。 - -## サブストリームを利用したサブグラフはサブグラフとどう違うのでしょうか? - -サブグラフは、オンチェーン イベントと、それらのイベントが Assemblyscript で記述されたハンドラーを介して変換される方法を指定するデータソースで構成されます。これらのイベントは、チェーン上でイベントが発生する順序に基づいて、順番に処理されます。 - -一方、Substreamsで動作するサブグラフは、Substreamsパッケージを参照する単一のデータソースを持ち、これはGraph Nodeによって処理されます。従来のサブグラフと比較して、Substreamsはより細かい粒度のオンチェーンデータにアクセスでき、また、大規模な並列処理の恩恵も受けることができます。これにより、処理時間が大幅に短縮される可能性があります。 - -## サブストリームを利用したサブグラフを使用する利点は何ですか? - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## サブストリームの利点は何ですか? - -サブストリームを使用すると、次のような多くの利点があります。 - -- コンポーザブル: レゴ ブロックのようなサブストリーム モジュールを積み重ね、コミュニティ モジュールを基にして公開データをさらに洗練させることができます。 - -- 高パフォーマンスのインデックス作成: 並列操作の大規模なクラスター (BigQuery を考えてください) を通じて、桁違いに高速なインデックス作成を実現します。 - -- 場所を選ばずにデータをどこにでも沈める: PostgreSQL、MongoDB、Kafka、サブグラフ、フラットファイル、Googleシート。 - -- プログラム可能: コードを使用して抽出をカスタマイズし、変換時の集計を実行し、複数のシンクの出力をモデル化します。 - -- JSON RPC の一部として利用できない追加データへのアクセス - -- Firehose のすべての利点。 - -## 消防ホースとは何ですか? - -[StreamingFast](https://www.streamingfast.io/) によって開発された Firehose は、ブロックチェーンの全履歴をこれまで見たことのない速度で処理するためにゼロから設計されたブロックチェーン データ抽出レイヤーです。ファイルベースでストリーミングファーストのアプローチを提供するこれは、StreamingFast のオープンソース テクノロジ スイートの中核コンポーネントであり、サブストリームの基盤です。 - -Firehose の詳細については、[documentation](https://firehose.streamingfast.io/) にアクセスしてください。 - -## 消防ホースの利点は何ですか? - -Firehose を使用すると、次のような多くの利点があります。 - -- 最低のレイテンシーとポーリングなし: ストリーミングファーストの方式で、Firehose ノードはブロック データを最初にプッシュするために競合するように設計されています。 - -- ダウンタイムの防止: 高可用性を実現するためにゼロから設計されています。 - -- ビートを見逃すことはありません: Firehose ストリーム カーソルは、フォークを処理し、どのような状況でも中断したところから続行するように設計されています。 - -- 最も豊富なデータ モデル: 残高の変更、完全なコール ツリー、内部トランザクション、ログ、ストレージの変更、ガス料金などが含まれる最適なデータ モデル。 - -- フラット ファイルの活用: ブロックチェーン データは、利用可能な最も安価で最適化されたコンピューティング リソースであるフラット ファイルに抽出されます。 - -## 開発者は、サブストリームを利用したサブグラフとサブストリームに関する詳細情報にどこでアクセスできますか? - -[Substreams ドキュメント](/substreams/introduction/) では、Substreams モジュールを構築する方法を説明します。 - -[Substreams-powered subgraphs ドキュメント](/subgraphs/cookbook/substreams-powered-subgraphs/) では、The Graph にデプロイするためにサブグラフをパッケージ化する方法が示されています。 - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## サブストリームにおけるRustモジュールの役割は何ですか? - -Rust モジュールは、サブグラフの AssemblyScript マッパーに相当します。これらは同様の方法で WASM にコンパイルされますが、プログラミング モデルにより並列実行が可能になります。これらは、生のブロックチェーン データに適用する変換と集計の種類を定義します。 - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## サブストリームを構成可能にするものは何ですか? - -サブストリームを使用すると、変換レイヤーで合成が行われ、キャッシュされたモジュールを再利用できるようになります。 - -例として、AliceはDEX価格モジュールを構築し、Bobはそれを使用して興味のあるいくつかのトークンのボリューム集計モジュールを構築し、Lisaは4つの個々のDEX価格モジュールを組み合わせて価格オラクルを作成することができます。単一のSubstreamsリクエストは、これらの個々のモジュールをまとめ、リンクしてより洗練されたデータのストリームを提供します。そのストリームはその後、サブグラフを作成し、消費者によってクエリされることができます。 - -## サブストリームを利用したサブグラフを構築してデプロイするにはどうすればよいでしょうか? - -Substreams を利用したサブグラフを [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) した後、Graph CLI を使用してそれを [Subgraph Studio](https://thegraph.com/studio/) にデプロイできます。 - -## サブストリームおよびサブストリームを利用したサブグラフの例はどこで見つけることができますか? - -[この Github リポジトリ](https://github.com/pinax-network/awesome-substreams) にアクセスして、サブストリームとサブストリームを利用したサブグラフの例を見つけることができます。 - -## SubstreamsとSubstreamsを活用したサブグラフがThe Graph Networkにとってどのような意味を持つのでしょうか? - -この統合は、非常に高いパフォーマンスのインデクシングと、コミュニティモジュールを活用し、それらを基に構築することによる大きな組み合わせ可能性を含む多くの利点を約束しています。 diff --git a/website/pages/ja/substreams/sps/triggers.mdx b/website/pages/ja/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/ja/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/ja/substreams/sps/tutorial.mdx b/website/pages/ja/substreams/sps/tutorial.mdx deleted file mode 100644 index b547721bc3c7..000000000000 --- a/website/pages/ja/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## 前提条件 - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/ko/sps/_meta.js b/website/pages/ko/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/ko/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ko/sps/introduction.mdx b/website/pages/ko/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/ko/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/ko/sps/sps-faq.mdx b/website/pages/ko/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/ko/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/ko/sps/triggers.mdx b/website/pages/ko/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/ko/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/ko/sps/tutorial.mdx b/website/pages/ko/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/ko/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/ko/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/ko/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/ko/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/ko/substreams/developing/_meta.js b/website/pages/ko/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/ko/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ko/substreams/developing/devcontainer.mdx b/website/pages/ko/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/ko/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/ko/substreams/developing/sinks/_meta.js b/website/pages/ko/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/ko/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ko/substreams/developing/sinks/sinks.mdx b/website/pages/ko/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/ko/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/ko/substreams/developing/solana/_meta.js b/website/pages/ko/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/ko/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ko/substreams/developing/solana/accountchanges.mdx b/website/pages/ko/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/ko/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/ko/substreams/developing/solana/solana.mdx b/website/pages/ko/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/ko/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/ko/substreams/developing/solana/transactions.mdx b/website/pages/ko/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/ko/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/ko/substreams/getting-started-substreams.mdx b/website/pages/ko/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/ko/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/ko/substreams/pubsubstreams.mdx b/website/pages/ko/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/ko/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/ko/substreams/sps/_meta.js b/website/pages/ko/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/ko/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/ko/substreams/sps/introduction.mdx b/website/pages/ko/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/ko/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/ko/substreams/sps/triggers.mdx b/website/pages/ko/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/ko/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/ko/substreams/sps/tutorial.mdx b/website/pages/ko/substreams/sps/tutorial.mdx deleted file mode 100644 index bb278b7f0eee..000000000000 --- a/website/pages/ko/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Prerequisites - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/mr/sps/_meta.js b/website/pages/mr/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/mr/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/mr/sps/introduction.mdx b/website/pages/mr/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/mr/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/mr/sps/sps-faq.mdx b/website/pages/mr/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/mr/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/mr/sps/triggers.mdx b/website/pages/mr/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/mr/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/mr/sps/tutorial.mdx b/website/pages/mr/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/mr/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/mr/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/mr/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/mr/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/mr/substreams/developing/_meta.js b/website/pages/mr/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/mr/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/mr/substreams/developing/devcontainer.mdx b/website/pages/mr/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/mr/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/mr/substreams/developing/sinks/_meta.js b/website/pages/mr/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/mr/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/mr/substreams/developing/sinks/sinks.mdx b/website/pages/mr/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/mr/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/mr/substreams/developing/solana/_meta.js b/website/pages/mr/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/mr/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/mr/substreams/developing/solana/accountchanges.mdx b/website/pages/mr/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/mr/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/mr/substreams/developing/solana/solana.mdx b/website/pages/mr/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/mr/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/mr/substreams/developing/solana/transactions.mdx b/website/pages/mr/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/mr/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/mr/substreams/getting-started-substreams.mdx b/website/pages/mr/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/mr/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/mr/substreams/pubsubstreams.mdx b/website/pages/mr/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/mr/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/mr/substreams/sps/_meta.js b/website/pages/mr/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/mr/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/mr/substreams/sps/introduction.mdx b/website/pages/mr/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/mr/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/mr/substreams/sps/sps-faq.mdx b/website/pages/mr/substreams/sps/sps-faq.mdx deleted file mode 100644 index ec24f97300ae..000000000000 --- a/website/pages/mr/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Substreams-powered subgraphs FAQ ---- - -## What are Substreams? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. - -## What are Substreams-powered subgraphs? - -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. - -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. - -## How are Substreams-powered subgraphs different from subgraphs? - -Subgraphs are made up of datasources which specify on-chain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen on-chain. - -By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular on-chain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. - -## What are the benefits of using Substreams-powered subgraphs? - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## What are the benefits of Substreams? - -There are many benefits to using Substreams, including: - -- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. - -- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). - -- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. - -- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. - -- Access to additional data which is not available as part of the JSON RPC - -- All the benefits of the Firehose. - -## What is the Firehose? - -Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. - -Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. - -## What are the benefits of the Firehose? - -There are many benefits to using Firehose, including: - -- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. - -- Prevents downtimes: Designed from the ground up for High Availability. - -- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. - -- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. - -- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. - -## Where can developers access more information about Substreams-powered subgraphs and Substreams? - -The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. - -The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## What is the role of Rust modules in Substreams? - -Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## What makes Substreams composable? - -When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. - -As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. - -## How can you build and deploy a Substreams-powered Subgraph? - -After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). - -## Where can I find examples of Substreams and Substreams-powered subgraphs? - -You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. - -## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? - -The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/mr/substreams/sps/triggers.mdx b/website/pages/mr/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/mr/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/mr/substreams/sps/tutorial.mdx b/website/pages/mr/substreams/sps/tutorial.mdx deleted file mode 100644 index 5291e4a404b3..000000000000 --- a/website/pages/mr/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## पूर्वतयारी - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/nl/sps/_meta.js b/website/pages/nl/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/nl/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/nl/sps/introduction.mdx b/website/pages/nl/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/nl/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/nl/sps/sps-faq.mdx b/website/pages/nl/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/nl/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/nl/sps/triggers.mdx b/website/pages/nl/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/nl/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/nl/sps/tutorial.mdx b/website/pages/nl/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/nl/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/nl/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/nl/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/nl/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/nl/substreams/developing/_meta.js b/website/pages/nl/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/nl/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/nl/substreams/developing/devcontainer.mdx b/website/pages/nl/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/nl/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/nl/substreams/developing/sinks/_meta.js b/website/pages/nl/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/nl/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/nl/substreams/developing/sinks/sinks.mdx b/website/pages/nl/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/nl/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/nl/substreams/developing/solana/_meta.js b/website/pages/nl/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/nl/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/nl/substreams/developing/solana/accountchanges.mdx b/website/pages/nl/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/nl/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/nl/substreams/developing/solana/solana.mdx b/website/pages/nl/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/nl/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/nl/substreams/developing/solana/transactions.mdx b/website/pages/nl/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/nl/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/nl/substreams/getting-started-substreams.mdx b/website/pages/nl/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/nl/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/nl/substreams/pubsubstreams.mdx b/website/pages/nl/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/nl/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/nl/substreams/sps/_meta.js b/website/pages/nl/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/nl/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/nl/substreams/sps/introduction.mdx b/website/pages/nl/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/nl/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/nl/substreams/sps/sps-faq.mdx b/website/pages/nl/substreams/sps/sps-faq.mdx deleted file mode 100644 index ec24f97300ae..000000000000 --- a/website/pages/nl/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Substreams-powered subgraphs FAQ ---- - -## What are Substreams? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. - -## What are Substreams-powered subgraphs? - -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. - -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. - -## How are Substreams-powered subgraphs different from subgraphs? - -Subgraphs are made up of datasources which specify on-chain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen on-chain. - -By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular on-chain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. - -## What are the benefits of using Substreams-powered subgraphs? - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## What are the benefits of Substreams? - -There are many benefits to using Substreams, including: - -- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. - -- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). - -- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. - -- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. - -- Access to additional data which is not available as part of the JSON RPC - -- All the benefits of the Firehose. - -## What is the Firehose? - -Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. - -Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. - -## What are the benefits of the Firehose? - -There are many benefits to using Firehose, including: - -- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. - -- Prevents downtimes: Designed from the ground up for High Availability. - -- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. - -- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. - -- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. - -## Where can developers access more information about Substreams-powered subgraphs and Substreams? - -The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. - -The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## What is the role of Rust modules in Substreams? - -Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## What makes Substreams composable? - -When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. - -As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. - -## How can you build and deploy a Substreams-powered Subgraph? - -After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). - -## Where can I find examples of Substreams and Substreams-powered subgraphs? - -You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. - -## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? - -The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/nl/substreams/sps/triggers.mdx b/website/pages/nl/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/nl/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/nl/substreams/sps/tutorial.mdx b/website/pages/nl/substreams/sps/tutorial.mdx deleted file mode 100644 index bb278b7f0eee..000000000000 --- a/website/pages/nl/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Prerequisites - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/pl/sps/_meta.js b/website/pages/pl/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/pl/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/pl/sps/introduction.mdx b/website/pages/pl/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/pl/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/pl/sps/sps-faq.mdx b/website/pages/pl/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/pl/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/pl/sps/triggers.mdx b/website/pages/pl/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/pl/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/pl/sps/tutorial.mdx b/website/pages/pl/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/pl/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/pl/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/pl/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/pl/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/pl/substreams/developing/_meta.js b/website/pages/pl/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/pl/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/pl/substreams/developing/devcontainer.mdx b/website/pages/pl/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/pl/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/pl/substreams/developing/sinks/_meta.js b/website/pages/pl/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/pl/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/pl/substreams/developing/sinks/sinks.mdx b/website/pages/pl/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/pl/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/pl/substreams/developing/solana/_meta.js b/website/pages/pl/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/pl/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/pl/substreams/developing/solana/accountchanges.mdx b/website/pages/pl/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/pl/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/pl/substreams/developing/solana/solana.mdx b/website/pages/pl/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/pl/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/pl/substreams/developing/solana/transactions.mdx b/website/pages/pl/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/pl/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/pl/substreams/getting-started-substreams.mdx b/website/pages/pl/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/pl/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/pl/substreams/pubsubstreams.mdx b/website/pages/pl/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/pl/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/pl/substreams/sps/_meta.js b/website/pages/pl/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/pl/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/pl/substreams/sps/introduction.mdx b/website/pages/pl/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/pl/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/pl/substreams/sps/sps-faq.mdx b/website/pages/pl/substreams/sps/sps-faq.mdx deleted file mode 100644 index ec24f97300ae..000000000000 --- a/website/pages/pl/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Substreams-powered subgraphs FAQ ---- - -## What are Substreams? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. - -## What are Substreams-powered subgraphs? - -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. - -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. - -## How are Substreams-powered subgraphs different from subgraphs? - -Subgraphs are made up of datasources which specify on-chain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen on-chain. - -By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular on-chain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. - -## What are the benefits of using Substreams-powered subgraphs? - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## What are the benefits of Substreams? - -There are many benefits to using Substreams, including: - -- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. - -- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). - -- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. - -- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. - -- Access to additional data which is not available as part of the JSON RPC - -- All the benefits of the Firehose. - -## What is the Firehose? - -Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. - -Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. - -## What are the benefits of the Firehose? - -There are many benefits to using Firehose, including: - -- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. - -- Prevents downtimes: Designed from the ground up for High Availability. - -- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. - -- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. - -- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. - -## Where can developers access more information about Substreams-powered subgraphs and Substreams? - -The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. - -The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## What is the role of Rust modules in Substreams? - -Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## What makes Substreams composable? - -When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. - -As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. - -## How can you build and deploy a Substreams-powered Subgraph? - -After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). - -## Where can I find examples of Substreams and Substreams-powered subgraphs? - -You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. - -## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? - -The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/pl/substreams/sps/triggers.mdx b/website/pages/pl/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/pl/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/pl/substreams/sps/tutorial.mdx b/website/pages/pl/substreams/sps/tutorial.mdx deleted file mode 100644 index bb278b7f0eee..000000000000 --- a/website/pages/pl/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Prerequisites - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/pt/sps/_meta.js b/website/pages/pt/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/pt/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/pt/sps/introduction.mdx b/website/pages/pt/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/pt/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/pt/sps/sps-faq.mdx b/website/pages/pt/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/pt/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/pt/sps/triggers.mdx b/website/pages/pt/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/pt/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/pt/sps/tutorial.mdx b/website/pages/pt/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/pt/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/pt/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/pt/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 47d3866e4ec0..000000000000 --- a/website/pages/pt/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Subgraphs movidos por substreams ---- - -[Substreams](/substreams/introduction/) é uma nova infraestrutura para o processamento de dados na blockchain, desenvolvida pela StreamingFast para a Graph Network. Um módulo de substreams pode gerar mudanças de entidade, que são compatíveis com entidades de Subgraph. Um subgraph pode usar um tal modelo de Substreams como uma fonte de dados, trazendo a velocidade de indexação e dados adicionais do Substreams aos desenvolvedores de subgraph. - -## Requisitos - -Este manual precisa de: [yarn](https://yarnpkg.com/); [as dependências necessárias para o desenvolvimento local da Substreams](https://substreams.streamingfast.io/documentation/consume/installing-the-cli); e a versão mais recente do Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## O manual - -> Este manual usa este [subgraph movido pelo Substreams como referência](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Como definir um pacote de Substreams - -Um pacote de Substreams é composto de tipos (definidos como [Protocol Buffers](https://protobuf.dev/)), módulos (escritos em Rust), e um arquivo `substreams.yaml` que referencia os tipos, e especifica como os módulos são ativados. [Visite a documentação de Substreams para aprender mais sobre o desenvolvimento de Substreams](/substreams/introduction/), e confira o [awesome-substreams](https://github.com/pinax-network/awesome-substreams) e o [manual de Substreams](https://github.com/pinax-network/substreams-cookbook) para mais exemplos. - -O pacote de Substreams em questão deteta publicações de contratos na Mainnet do Ethereum, com rastreio do bloco de criação e horas para todos os contratos recém-lançados. Para fazer isto, há um tipo dedicado de `Contrato` no `/proto/example.proto` ([aprenda mais sobre a definição de Buffers de Protocolo](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -A lógica central do pacote de Substreams é um módulo `map_contract` em `lib.rs`, que processa cada bloco, assim filtrando chamadas de Criação que não foram revertidas e retornando `Contratos`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -Um pacote de Substreams também pode ser usado por um subgraph enquanto tiver um módulo que gere mudanças de entidade compatíveis. O pacote de Substreams usado como exemplo tem um módulo `graph_out` adicional no `lib.rs` que retorna um `substreams_entity_change::pb::entity::EntityChanges`, que pode então ser processado pelo Graph Node. - -> O `substreams_entity_change` também tem uma função `Tables` dedicada à geração simples de mudanças de entidade ([documentação](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). As Mudanças de Entidade geradas devem ser compatíveis com as entidades `schema.graphql` definidas no `subgraph.graphql` do subgraph correspondente. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -Estes tipos e módulos são juntados no `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # o nome a ser usado no .spkg - version: v1.0.1 # a versão a ser usada na criação do .spkg - -imports: # dependências - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # especifica tipos personalizados a serem usados por módulos Substreams - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # especifica módulos com suas entradas e saídas - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # este tipo pode ser consumido pelo Graph Node -``` - -Podes conferir o "fluxo" geral de um Bloco, de `map_contract` a `graph_out` ao executar o `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -Para preparar este pacote de Substreams para consumo por um subgraph, os seguintes comandos devem ser executados: - -```bash -yarn substreams:protogen # gera tipos no /src/pb -yarn substreams:build # constroi as substreams -yarn substreams:package # empacota as substreams em um arquivo .spkg - -# como alternativa, o yarn substreams:prepare chama todos os comandos acima -``` - -> Estes scripts são definidos no pacote `package.json` se quiser entender os comandos subjacentes - -Isto gera um arquivo `spkg` baseado no nome e na versão do pacote da `substreams.yaml`. O arquivo `spkg` tem toda a informação necessária para que o Graph Node ingeste este pacote Substreams. - -> Em caso de atualização do pacote de Substreams, dependendo das mudanças feitas, pode ser necessário executar alguns dos — ou todos — os comandos acima para que o `spkg` esteja atualizado. - -## Definição de um subgraph movido a Substreams - -Subgraphs movidos a Substreams introduzem um novo `tipo` de fonte de dados, "substreams". Tais subgraphs só podem ter uma fonte de dados. - -Esta fonte de dados deve especificar a rede indexada, o pacote de Substreams ('spkg') como um local relativo de arquivos, e o módulo dentro daquele pacote de Substreams que produz mudanças de entidade compatíveis com o subgraph (neste caso 'map_entity_changes', do pacote de Substreams acima). O mapeamento é especificado, mas apenas identifica o tipo de mapeamento ("substreams/graph-entities") e a apiVersion. - -> Atualmente, o Subgraph Studio e a Graph Network apoiam subgraphs movidos a Substreams que indexam a `mainnet` (Mainnet do Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -O 'subgraph.yaml' também referencia um arquivo schema. Os requerimentos para este arquivo são os mesmos, mas as entidades especificadas devem ser compatíveis com as mudanças de entidade produzidas pelo módulo de Substreams referenciados no 'subgraph.yaml'. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Vendo acima, os programadores de subgraph podem usar a Graph CLI para editar este subgraph movido pelo Substreams. - -> Subgraphs movidos a substreams que indexam a mainnet do Ethereum podem ser editados ao [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # instala o graph-cli -yarn subgraph:build # constroi o subgraph -yarn subgraph:deploy # publica o subgraph -``` - -Pronto! Está construído e editado um subgraph movido a Substreams. - -## Servindo subgraphs movidos por substreams - -Para poder servir subgraphs movidos a Substreams, o Graph Node deve ser configurado com um provedor de Substreams para a rede relevante, assim como um Firehose ou RPC para rastrear a cabeça da chain. Estes provedores podem ser configurados através de um arquivo 'config.toml': - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/pt/substreams/developing/_meta.js b/website/pages/pt/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/pt/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/pt/substreams/developing/devcontainer.mdx b/website/pages/pt/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/pt/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/pt/substreams/developing/sinks/_meta.js b/website/pages/pt/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/pt/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/pt/substreams/developing/sinks/sinks.mdx b/website/pages/pt/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/pt/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/pt/substreams/developing/solana/_meta.js b/website/pages/pt/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/pt/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/pt/substreams/developing/solana/accountchanges.mdx b/website/pages/pt/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/pt/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/pt/substreams/developing/solana/solana.mdx b/website/pages/pt/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/pt/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/pt/substreams/developing/solana/transactions.mdx b/website/pages/pt/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/pt/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/pt/substreams/getting-started-substreams.mdx b/website/pages/pt/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/pt/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/pt/substreams/pubsubstreams.mdx b/website/pages/pt/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/pt/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/pt/substreams/sps/_meta.js b/website/pages/pt/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/pt/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/pt/substreams/sps/introduction.mdx b/website/pages/pt/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/pt/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/pt/substreams/sps/sps-faq.mdx b/website/pages/pt/substreams/sps/sps-faq.mdx deleted file mode 100644 index cae95563a993..000000000000 --- a/website/pages/pt/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Perguntas frequentes sobre subgraphs movidos por substreams ---- - -## O que são Substreams? - -Desenvolvido pela [StreamingFast](https://www.streamingfast.io/), o Substreams é um motor de processamento de poder excepcional, capaz de consumir fluxos ricos de dados em blockchain. O Substreams lhe permite refinar e moldar dados em blockchain para serem digeridos rápida e suavemente por aplicativos de utilizador final. Mais especificamente, o Substreams é um motor paralelizado e agnóstico a blockchains, que põe transmissões em primeiro lugar e serve como uma camada de transformação de dados em blockchain. Movido pelo [Firehose](https://firehose.streamingfast.io/), ele permite que programadores escrevam módulos em Rust, construam sobre módulos da comunidade, providenciem indexações de altíssimo desempenho, e mandar seus dados para qualquer destino com [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink). - -Vá à [Documentação do Substreams](/substreams/introduction/) para aprender mais sobre Substreams. - -## O que são subgraphs movidos por substreams? - -[Subgraphs movidos a Substreams](/subgraphs/cookbook/substreams-powered-subgraphs/) combinam o poder do Substreams com a consultabilidade de subgraphs. Ao publicar um subgraph movido a Substreams, os dados produzidos pelas transformações no Substreams podem [resultar em mudanças de entidade](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), que são compatíveis com entidades no subgraph. - -Se você já for familiar com a programação de subgraphs, então note que subgraphs movidos a Substreams podem ser consultados do mesmo jeito que se tivessem sido produzidos pela camada de transformação em AssemblyScript, com todos os benefícios do Subgraph, como a providência de uma API GraphQL dinâmica e flexível. - -## Como subgraphs movidos a Substreams são diferentes de subgraphs? - -Subgraphs são compostos de fontes de dados que especificam eventos on-chain, e como estes eventos devem ser transformados através de handlers escritos em AssemblyScript. Estes eventos são processados em sequência, com base na ordem na qual eventos acontecem na chain. - -Ao contrário, subgraphs movidos a substreams têm uma única fonte de dados que referencia um pacote de substreams, processado pelo Graph Node. Substreams têm acesso a mais dados granulares on-chain em comparação a subgraphs convencionais, e também podem se beneficiar de um processamento paralelizado em massa, o que pode resultar em tempos de processamento muito mais rápidos. - -## Quais os benefícios do uso de subgraphs movidos a Substreams? - -Subgraphs movidos a Substreams combinam todos os benefícios do Substreams com o potencial de query de subgraphs. Eles também trazem mais composabilidade e indexação de alto desempenho ao The Graph. Eles também resultam em novos casos de uso de dados; por exemplo, após construir o seu Subgraph movido a Substreams, você pode reutilizar os seus [módulos de Substreams](https://substreams.streamingfast.io/documentation/develop/manifest-modules) para usar [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) diferentes, como PostgreSQL, MongoDB e Kafka. - -## Quais os benefícios do Substreams? - -Usar o Substreams incorre muitos benefícios, que incluem: - -- Compostável: Você pode empilhar módulos de Substreams como se fossem blocos de LEGO, e construir em cima de módulos da comunidade, para refinar dados públicos. - -- Indexação de alto desempenho: Indexação muito mais rápida através de clusters de larga escala de operações paralelas (como o BigQuery). - -- Mergulho em qualquer lugar: Mergulhe seus dados onde quiser: PostgreSQL, MongoDB, Kafka, subgraphs, arquivos planos, Google Sheets. - -- Programável: Use códigos para personalizar a extração, realizar agregações de tempo de transformação, e modelar o seu resultado para vários sinks. - -- Acesso a dados tradicionais que não são disponíveis como parte do RPC em JSON - -- Todos os benefícios do Firehose. - -## O que é o Firehose? - -Desenvolvido pela [StreamingFast](https://www.streamingfast.io/), o Firehose é uma camada de extração de dados em blockchain desenhada do zero para processar o histórico completo de blockchains em velocidades nunca antes vistas. Com uma abordagem baseada em arquivos e que dá prioridade a transmissões, ele é um componente central do conjunto de tecnologias de código aberto da StreamingFast, e a fundação do Substreams. - -Confira a [documentação](https://firehose.streamingfast.io/) para aprender mais sobre o Firehose. - -## Quais os benefícios do Firehose? - -Há muitos benefícios do uso do Firehose, que incluem: - -- Latência menor: De forma que prioriza as transmissões, os nodes do Firehouse são desenhados para correrem para revelar os dados do bloco em primeiro lugar. - -- Evita downtimes: Desenhado do zero para Alta Disponibilidade. - -- Não perde nada: O cursor de transmissões do Firehose é desenhado para lidar com forks e continuar de onde você parou em qualquer condição. - -- Modelo rico de dados:  O melhor modelo de dados, que inclui as mudanças de saldo, a árvore de chamadas completa, transações internas, logs, mudanças de armazenamento, custos de gas, e mais. - -- Uso de arquivos planos: Dados de blockchain são extraídos em arquivos planos, o recurso de computação mais barato e otimizado disponível. - -## Onde programadores podem acessar mais informações sobre Substreams e subgraphs movidos a Substreams? - -A [documentação do Substreams](/substreams/introduction/) lhe ensinará como construir módulos do Substreams. - -A [documentação de subgraphs movidos a Substreams](/subgraphs/cookbook/substreams-powered-subgraphs/) lhe ensinará como empacotá-los para a publicação no The Graph. - -A [ferramenta de Codegen no Substreams mais recente](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) permitirá ao programador inicializar um projeto no Substreams sem a necessidade de código. - -## Qual é o papel de módulos em Rust no Substreams? - -Módulos de Rust são o equivalente aos mapeadores em AssemblyScript em subgraphs. Eles são compilados em WASM de forma parecida, mas o modelo de programação permite execuções paralelas. Eles definem a categoria de transformações e agregações que você quer aplicar aos dados de blockchain crus. - -Veja a [documentação dos módulos](https://substreams.streamingfast.io/documentation/develop/manifest-modules) para mais detalhes. - -## O que faz o Substreams compostável? - -Ao usar o Substreams, a composição é realizada na camada de transformação, permitindo o uso de módulos em cache. - -Como exemplo, Fulana pode construir um módulo de preço de DEX, Sicrano pode usá-lo para construir um agregador de volume para alguns tokens do seu interesse, e Beltrana pode combinar quatro módulos de preço de DEX individuais para criar um oráculo de preço. Um único pedido do Substreams empacotará todos estes módulos e os interligará para oferecer uma transmissão de dados muito mais refinada. Aquela transmissão pode então ser usada para popular um subgraph, e ser consultada pelos consumidores. - -## Como construir e publicar um Subgraph movido a Substreams? - -(/subgraphs/cookbook/substreams-powered-subgraphs/) um Subgraph movido a Substreams, é possível usar o Graph CLI para publicá lo no [Subgraph Studio](https://thegraph.com/studio/). - -## Onde posso encontrar exemplos de Substreams e subgraphs movidos a Substreams? - -Você pode visitar [este repo do Github](https://github.com/pinax-network/awesome-substreams) para encontrar exemplos de Substreams e subgraphs movidos a Substreams. - -## O que Substreams e subgraphs movidos a Substreams significam para a Graph Network? - -A integração promete vários benefícios, incluindo indexações de altíssimo desempenho e mais composabilidade com o uso de módulos de comunidade e construção por cima deles. diff --git a/website/pages/pt/substreams/sps/triggers.mdx b/website/pages/pt/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/pt/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/pt/substreams/sps/tutorial.mdx b/website/pages/pt/substreams/sps/tutorial.mdx deleted file mode 100644 index 5562eb4ee073..000000000000 --- a/website/pages/pt/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Pré-requisitos - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusão - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/ro/sps/_meta.js b/website/pages/ro/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/ro/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ro/sps/introduction.mdx b/website/pages/ro/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/ro/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/ro/sps/sps-faq.mdx b/website/pages/ro/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/ro/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/ro/sps/triggers.mdx b/website/pages/ro/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/ro/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/ro/sps/tutorial.mdx b/website/pages/ro/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/ro/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/ro/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/ro/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/ro/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/ro/substreams/developing/_meta.js b/website/pages/ro/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/ro/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ro/substreams/developing/devcontainer.mdx b/website/pages/ro/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/ro/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/ro/substreams/developing/sinks/_meta.js b/website/pages/ro/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/ro/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ro/substreams/developing/sinks/sinks.mdx b/website/pages/ro/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/ro/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/ro/substreams/developing/solana/_meta.js b/website/pages/ro/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/ro/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ro/substreams/developing/solana/accountchanges.mdx b/website/pages/ro/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/ro/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/ro/substreams/developing/solana/solana.mdx b/website/pages/ro/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/ro/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/ro/substreams/developing/solana/transactions.mdx b/website/pages/ro/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/ro/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/ro/substreams/getting-started-substreams.mdx b/website/pages/ro/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/ro/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/ro/substreams/pubsubstreams.mdx b/website/pages/ro/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/ro/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/ro/substreams/sps/_meta.js b/website/pages/ro/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/ro/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/ro/substreams/sps/introduction.mdx b/website/pages/ro/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/ro/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/ro/substreams/sps/sps-faq.mdx b/website/pages/ro/substreams/sps/sps-faq.mdx deleted file mode 100644 index ec24f97300ae..000000000000 --- a/website/pages/ro/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Substreams-powered subgraphs FAQ ---- - -## What are Substreams? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. - -## What are Substreams-powered subgraphs? - -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. - -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. - -## How are Substreams-powered subgraphs different from subgraphs? - -Subgraphs are made up of datasources which specify on-chain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen on-chain. - -By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular on-chain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. - -## What are the benefits of using Substreams-powered subgraphs? - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## What are the benefits of Substreams? - -There are many benefits to using Substreams, including: - -- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. - -- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). - -- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. - -- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. - -- Access to additional data which is not available as part of the JSON RPC - -- All the benefits of the Firehose. - -## What is the Firehose? - -Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. - -Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. - -## What are the benefits of the Firehose? - -There are many benefits to using Firehose, including: - -- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. - -- Prevents downtimes: Designed from the ground up for High Availability. - -- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. - -- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. - -- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. - -## Where can developers access more information about Substreams-powered subgraphs and Substreams? - -The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. - -The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## What is the role of Rust modules in Substreams? - -Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## What makes Substreams composable? - -When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. - -As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. - -## How can you build and deploy a Substreams-powered Subgraph? - -After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). - -## Where can I find examples of Substreams and Substreams-powered subgraphs? - -You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. - -## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? - -The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/ro/substreams/sps/triggers.mdx b/website/pages/ro/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/ro/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/ro/substreams/sps/tutorial.mdx b/website/pages/ro/substreams/sps/tutorial.mdx deleted file mode 100644 index bb278b7f0eee..000000000000 --- a/website/pages/ro/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Prerequisites - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/ru/sps/_meta.js b/website/pages/ru/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/ru/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ru/sps/introduction.mdx b/website/pages/ru/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/ru/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/ru/sps/sps-faq.mdx b/website/pages/ru/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/ru/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/ru/sps/triggers.mdx b/website/pages/ru/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/ru/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/ru/sps/tutorial.mdx b/website/pages/ru/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/ru/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/ru/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/ru/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 41a190869890..000000000000 --- a/website/pages/ru/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Субграфы, работающие на основе субпотоков (Substreams) ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Требования - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Используйте справочный материал - -> В качестве справочного материала здесь используется этот [субграф на основе субпотоков в качестве ссылки](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Определение пакета субпотоков - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -Рассматриваемый пакет Substreams обнаруживает развертывания контрактов в основной сети Ethereum, отслеживая блок создания и временную метку для всех вновь развернутых контрактов. Для этого в `/proto/example.proto` есть специальный тип `Contract` ([узнайте больше об определении Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -Основной логикой пакета Substreams является модуль `map_contract` в `lib.rs `, который обрабатывает каждый блок, фильтруя вызовы Create, которые не были отменены, возвращая `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -Пакет Substreams может использоваться субграфом, если у него есть модуль, который выдает совместимые изменения объектов. В примере пакета Substreams есть дополнительный модуль `graph_out` в `lib.rs` который возвращает выходные данные `substreams_entity_change::pb::entity::EntityChanges`, которые могут быть обработаны Graph Node. - -> В крейте `substreams_entity_change` также есть специальная функция `Tables` для простой генерации изменений объектов ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). Сгенерированные изменения объектов должны быть совместимы с объектами `schema.graphql`, определенными в `subgraph.graphql` соответствующего субграфа. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -Эти типы и модули объединены в `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -Вы можете проверить общий "поток" из Блока от `map_contract` до `graph_out`, запустив `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -Чтобы подготовить этот пакет субпотоков к использованию субграфом, необходимо выполнить следующие команды: - -```bash -yarn substreams:protogen # генерирует типы в /src/pb -yarn substreams:build # создает субпотоки -yarn substreams:package # упаковывает субпотоки в файл .spkg - -# в качестве альтернативы, yarn substreams:prepare вызывают все вышеперечисленные команды -``` - -> Эти скрипты определены в файле `package.json`, если вы хотите понять базовые команды субпотоков - -При этом создается файл `spkg` на основе имени и версии пакета из `substreams.yaml`. Файл `spkg` содержит всю информацию, которая необходима Graph Node для приема этого пакета субпотоков. - -> Если Вы обновите пакет субпотоков, в зависимости от внесенных Вами изменений, Вам может потребоваться выполнить некоторые или все вышеперечисленные команды, чтобы `spkg` был обновлен. - -## Определение субграфа, работающего на основе субпотоков - -Субграфы, работающие на основе на субпотоков, вводят в употребление новый "вид" источника данных - "субпотоки". Такие субграфы могут иметь только один источник данных. - -В этом источнике данных должна быть указана индексированная сеть, пакет Substreams (`spkg`) в качестве относительного местоположения файла и модуль в этом пакете Substreams, который производит совместимые с субграфами изменения объектов (в данном случае `map_entity_changes` из пакета Substreams, указанного выше). Мэппинг указан, но просто идентифицирует вид мэппинга ("substreams/graph-entities") и apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -`subgraph.yaml` также ссылается на файл схемы. Требования к этому файлу не изменились, но указанные объекты должны быть совместимы с изменениями объектов, произведенными модулем Substreams, на который ссылается `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Учитывая вышеизложенное, разработчики субграфов могут использовать Graph CLI для развертывания этого субграфа, работающего на основе субпотоков. - -> Субграфы, работающие на основе субпотоков, индексирующие основную сеть Ethereum, могут быть развернуты в [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -Вот и все! Вы создали и развернули субграф, работающий на основе субпотоков. - -## Обслуживание субграфов, работающих на основе субпотоков - -Для обслуживания субграфов, работающих на основе субпотоков, Graph Node должен быть сконфигурирован с соответствующей сетью провайдера субпотоков, а также с Firehose или RPC для отслеживания головного блока чейна. Эти провайдеры могут быть настроены с помощью файла `config.toml`: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/ru/substreams/developing/_meta.js b/website/pages/ru/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/ru/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ru/substreams/developing/devcontainer.mdx b/website/pages/ru/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/ru/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/ru/substreams/developing/sinks/_meta.js b/website/pages/ru/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/ru/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ru/substreams/developing/sinks/sinks.mdx b/website/pages/ru/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/ru/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/ru/substreams/developing/solana/_meta.js b/website/pages/ru/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/ru/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ru/substreams/developing/solana/accountchanges.mdx b/website/pages/ru/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/ru/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/ru/substreams/developing/solana/solana.mdx b/website/pages/ru/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/ru/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/ru/substreams/developing/solana/transactions.mdx b/website/pages/ru/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/ru/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/ru/substreams/getting-started-substreams.mdx b/website/pages/ru/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/ru/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/ru/substreams/pubsubstreams.mdx b/website/pages/ru/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/ru/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/ru/substreams/sps/_meta.js b/website/pages/ru/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/ru/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/ru/substreams/sps/introduction.mdx b/website/pages/ru/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/ru/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/ru/substreams/sps/sps-faq.mdx b/website/pages/ru/substreams/sps/sps-faq.mdx deleted file mode 100644 index d9689088d891..000000000000 --- a/website/pages/ru/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Часто задаваемые вопросы о субграфах, работающих на основе субпотоков (Substreams) ---- - -## Что такое субпотоки? - -Substreams (Субпотоки), разработанные [StreamingFast](https://www.streamingfast.io/), представляют собой исключительно мощный механизм обработки, способный потреблять обширные потоки блокчейн-данных. Субпотоки позволяют оптимизировать и формировать данные блокчейна для быстрого и бесперебойного использования приложениями конечных пользователей. В частности, Субпотоки - это независимый от блокчейна, распараллеленный и ориентированный на потоковую передачу движок, служащий в качестве уровня преобразования данных блокчейна. Работая на базе [Firehose](https://firehose.streamingfast.io), он позволяет разработчикам писать модули на языке Rust, использовать модули сообщества,обеспечивать крайне высокую производительность индексирования и [отправлять](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) свои данные в любое место. - -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. - -## Что такое субграфы, работающие на основе Субпотоков? - -[Субграфы, работающие на основе Субпотоков](/subgraphs/cookbook/substreams-powered-subgraphs/) сочетают в себе мощь Субпотоков с возможностью запроса субграфов. При публикации Субграфа, работающего на основе Субпотоков, данные, полученные в результате преобразований Субпотоков, могут [выводить изменения объекта](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), совместимые с объектами субграфа. - -Если Вы уже знакомы с разработкой субграфов, обратите внимание на то, что к тому же можно запрашивать субграфы, работающие на основе Субпотоков, точно так же, как если бы они были созданы на уровне преобразования AssemblyScript, со всеми преимуществами Субграфа, такими как предоставление динамического и гибкого GraphQL API. - -## Чем субграфы, работающие на основе Субпотоков, отличаются от субграфов? - -Субграфы состоят из источников данных, которые определяют события в цепочке и то, как эти события должны быть преобразованы с помощью обработчиков, написанных на Assemblyscript. Эти события обрабатываются последовательно в зависимости от того, в каком порядке события происходят в цепочке. - -Напротив, субграфы, работающие на основе субпотоков, имеют один источник данных, который ссылается на пакет субпотоков, обрабатываемый the Graph Node. Субпотоки имеют доступ к дополнительным детализированным данным в цепочке по сравнению с обычными субграфами, а также могут извлекать выгоду из массового распараллеливания обработки, что может подразумевать гораздо более быстрое время обработки. - -## Каковы преимущества использования субграфов, работающих на основе Субпотоков? - -Субграфы, работающие на основе Субпотоков, сочетают в себе все преимущества Субпотоков с возможностью запроса субграфов.Они обеспечивают более высокую совместимость и высокопроизводительное индексирование в The Graph. Они также позволяют создавать новые варианты использования данных; например, после того, как Вы создали свой субграф на базе Субпотоков, Вы можете повторно использовать свои [модули Субпотоков](https://substreams.streamingfast.io/documentation/develop/manifest-modules) для вывода в разные [приёмники](https://substreams.streamingfast.io/reference-and-specs/manifests#sink), такие как PostgreSQL, MongoDB и Kafka. - -## В чем преимущества Субпотоков? - -Использование Субпотоков имеет много преимуществ, в том числе: - -- Компонуемость: Вы можете объединять модули Субпотоков, как блоки LEGO, и опираться на модули сообщества, дополнительно уточняя общедоступные данные. - -- Высокопроизводительное индексирование: индексирование на порядки быстрее благодаря крупномасштабным кластерам параллельных операций (как пример, BigQuery). - -- Возможность загружать куда угодно: Загружайте Ваши данные в любое удобное для Вас место: PostgreSQL, MongoDB, Kafka, субграфы, плоские файлы, Google Sheets. - -- Программируемость: Используйте код для настройки извлечения, выполнения агрегирования во время преобразования и моделирования выходных данных для нескольких приемников. - -- Доступ к дополнительным данным, недоступным в составе JSON RPC - -- Все преимущества Firehose. - -## Что такое Firehose? - -Firehose, разработанный [StreamingFast](https://www.streamingfast.io/), представляет собой уровень извлечения данных блокчейна, разработанный с нуля для обработки полной истории блокчейнов на ранее невиданных скоростях. Обеспечивая подход, основанный на файлах и потоковой передаче, он является основным компонентом пакета технологий Streamingfast с открытым исходным кодом и основой для Субпотоков. - -Перейдите к [documentation](https://firehose.streamingfast.io/), чтобы узнать больше о Firehose. - -## В чем преимущества Firehose? - -Использование Firehose имеет много преимуществ, в том числе: - -- Наименьшая задержка и отсутствие опроса: В режиме потоковой передачи узлы Firehose спроектированы таким образом, чтобы первыми передавать данные блока. - -- Предотвращает простои: Разработан с нуля для обеспечения высокой доступности. - -- Никогда не пропустите ни одного момента: Курсор потока Firehose предназначен для обработки форков и продолжения работы с того места, где Вы остановились, в любых условиях. - -- Богатейшая модель данных:  Лучшая модель данных, которая включает изменения баланса, полное дерево вызовов, внутренние транзакции, логи, изменения в хранилище, затраты на газ и многое другое. - -- Использует плоские файлы: Данные блокчейна извлекаются в плоские файлы — самый дешевый и наиболее оптимизированный доступный вычислительный ресурс. - -## Где разработчики могут получить доступ к дополнительной информации о субграфах работающих на основе Субпотоков и о Субпотоках? - -The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. - -В документации [Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) показано, как упаковать их для развертывания в The Graph. - -[Новейший инструмент Substreams Codegen](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) позволит Вам загрузить проект Substreams без использования какого-либо кода. - -## Какова роль модулей Rust в Субпотоках? - -Модули Rust - это эквивалент мапперов AssemblyScript в субграфах. Они компилируются в WASM аналогичным образом, но модель программирования допускает параллельное выполнение. Они определяют, какие преобразования и агрегации необходимо применить к необработанным данным блокчейна. - -Подробную информацию см. в [документации по модулям](https://substreams.streamingfast.io/documentation/develop/manifest-modules). - -## Что делает Субпотоки компонуемыми? - -При использовании Субпотоков компоновка происходит на уровне преобразования, что позволяет повторно использовать кэшированные модули. - -Например, Алиса может создать ценовой модуль DEX, Боб может использовать его для создания агрегатора объемов для некоторых интересующих его токенов, а Лиза может объединить четыре отдельных ценовых модуля DEX, чтобы создать ценовой оракул. Один запрос Субпотоков упакует все эти отдельные модули, свяжет их вместе, чтобы предложить гораздо более уточненный поток данных. Затем этот поток может быть использован для заполнения субграфа и запрашиваться потребителями. - -## Как Вы можете создать и развернуть субграф, работающий на основе Субпотоков? - -После [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) субграфа, работающего на основе Субпотоков, Вы можете использовать the Graph CLI для его развертывания в [Subgraph Studio](https://thegraph.com/studio /). - -## Где я могу найти примеры Субпотоков и субграфов, работающих на основе Субпотоков? - -Вы можете посетить [этот репозиторий на Github](https://github.com/pinax-network/awesome-substreams), чтобы найти примеры Субпотоков и субграфов, работающих на основе Субпотоков. - -## Что означают Субпотоки и субграфы, работающие на основе Субпотоков, для сети The Graph? - -Интеграция обещает множество преимуществ, включая чрезвычайно высокопроизводительную индексацию и большую компонуемость за счет использования модулей сообщества и развития на их основе. diff --git a/website/pages/ru/substreams/sps/triggers.mdx b/website/pages/ru/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/ru/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/ru/substreams/sps/tutorial.mdx b/website/pages/ru/substreams/sps/tutorial.mdx deleted file mode 100644 index 6ade2c0d8816..000000000000 --- a/website/pages/ru/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Предварительные требования - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/sv/sps/_meta.js b/website/pages/sv/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/sv/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/sv/sps/introduction.mdx b/website/pages/sv/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/sv/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/sv/sps/sps-faq.mdx b/website/pages/sv/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/sv/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/sv/sps/triggers.mdx b/website/pages/sv/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/sv/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/sv/sps/tutorial.mdx b/website/pages/sv/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/sv/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/sv/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/sv/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index e7553043450b..000000000000 --- a/website/pages/sv/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-drivna subgrafer ---- - -[Substreams](/substreams/introduction/) är en ny ramverk för att behandla blockkedjedata som utvecklats av StreamingFast för The Graph Network. Ett Substreams-modul kan generera ändringar i entiteter som är kompatibla med Subgraph-entiteter. En subgraf kan använda en sådan Substreams-modul som en datakälla och därmed ta del av Substreams indexeringshastighet och ytterligare data för subgrafutvecklare. - -## Krav - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Skaffa kokboken - -> Den här kokboken använder denna [Substreams-powered subgraph som referens](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Definiera ett Substreams-paket - -En Substreams-paket består av typer (definierade som [Protocol Buffers](https://protobuf.dev/)), moduler (skrivna i Rust) och en `substreams.yaml`-fil som refererar till typerna och specificerar hur modulerna utlöses. [Besök Substreams-dokumentationen för att lära dig mer om Substreams-utveckling](/substreams/introduction/), och kolla in [awesome-substreams](https://github.com/pinax-network/awesome-substreams) och [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) för fler exempel. - -Substreams-paketet i fråga upptäcker kontraktsdistributioner på Mainnet Ethereum, spårar skapandeblocket och tidsstämpeln för alla nyligen distribuerade kontrakt. För att göra detta finns det en dedikerad "kontrakt"-typ i "/proto/example.proto" ([läs mer om att definiera protokollbuffertar](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -Kärnlogiken i Substreams-paketet är en `map_contract`-modul i `lib.rs`, som bearbetar varje block, filtrerar efter Skapa-anrop som inte återgick, returnerar `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -Ett Substreams-paket kan användas av en subgraf så länge det har en modul som matar ut kompatibla enhetsändringar. Exemplet på Substreams-paketet har en extra `graph_out`-modul i `lib.rs` som returnerar en `substreams_entity_change::pb::entity::EntityChanges`-utdata, som kan bearbetas av Graph Node. - -> "substreams_entity_change"-lådan har också en dedikerad "Tables"-funktion för att helt enkelt generera entitetsändringar ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). Entitetsändringarna som genereras måste vara kompatibla med "schema.graphql"-entiteterna som definieras i "subgraph.graphql" i motsvarande subgraf. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -Dessa typer och moduler dras ihop i `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -Du kan kontrollera det övergripande "flödet" från ett block, till `map_contract` till `graph_out` genom att köra `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -För att förbereda detta Substreams paket för konsumtion av en subgraf måste du köra följande kommandon: - -```bash -yarn substreams:protogen # genererar typer i /src/pb -yarn substreams:build # bygger substreams -yarn substreams:package # paketerar substreams i en .spkg-fil - -# alternativt anropar yarn substreams:prepare alla ovanstående kommandon -``` - -> Dessa skript definieras i filen `package.json` om du vill förstå de underliggande substreams-kommandona - -Detta genererar en `spkg`-fil baserat på paketnamnet och versionen från `substreams.yaml`. `spkg`-filen har all information som Graph Node behöver för att mata in detta Substreams-paket. - -> Om du uppdaterar Substreams-paketet, beroende på de ändringar du gör, kan du behöva köra några eller alla ovanstående kommandon så att `spkg` är uppdaterad. - -## Definiera en Substream-driven subgraf - -Substreams-drivna subgrafer introducerar en ny "typ" av datakälla, "substreams". Sådana subgrafer kan bara ha en datakälla. - -Denna datakälla måste ange det indexerade nätverket, Substreams-paketet ("spkg") som en relativ filplats och modulen i det Substreams-paketet som producerar subgrafkompatibla entitetsändringar (i detta fall "map_entity_changes", från Substreams-paketet ovan). Mappningen är specificerad, men identifierar helt enkelt mappningstypen ("substreams/graph-entities") och apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -`subgraph.yaml` refererar också till en schemafil. Kraven för denna fil är oförändrade, men de angivna entiteterna måste vara kompatibla med entitetsändringarna som produceras av Substreams-modulen som refereras till i `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "Tidsstämpeln när kontraktet implementerades" - timestamp: String! - - "Blocknummer för kontraktsimplementeringen" - blockNumber: BigInt! -} -``` - -Med tanke på ovanstående kan subgraf utvecklare använda Graph CLI för att distribuera denna Substreams-drivna subgraf. - -> Underströmsdrivna subgrafer som indexerar mainnet Ethereum kan distribueras till [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # bygg subgrafen -yarn subgraph:deploy # deploy the subgraph -``` - -Det är allt! Du har byggt och distribuerat en Substreams-drivna subgraf. - -## Visa substreams-drivna subgrafer - -För att kunna betjäna Substreams-drivna subgrafer måste Graph Node konfigureras med en Substreams-leverantör för det relevanta nätverket, samt en Firehose eller RPC för att spåra kedjehuvudet. Dessa leverantörer kan konfigureras via en `config.toml`-fil: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/sv/substreams/developing/_meta.js b/website/pages/sv/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/sv/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/sv/substreams/developing/devcontainer.mdx b/website/pages/sv/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/sv/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/sv/substreams/developing/sinks/_meta.js b/website/pages/sv/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/sv/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/sv/substreams/developing/sinks/sinks.mdx b/website/pages/sv/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/sv/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/sv/substreams/developing/solana/_meta.js b/website/pages/sv/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/sv/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/sv/substreams/developing/solana/accountchanges.mdx b/website/pages/sv/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/sv/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/sv/substreams/developing/solana/solana.mdx b/website/pages/sv/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/sv/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/sv/substreams/developing/solana/transactions.mdx b/website/pages/sv/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/sv/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/sv/substreams/getting-started-substreams.mdx b/website/pages/sv/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/sv/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/sv/substreams/pubsubstreams.mdx b/website/pages/sv/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/sv/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/sv/substreams/sps/_meta.js b/website/pages/sv/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/sv/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/sv/substreams/sps/introduction.mdx b/website/pages/sv/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/sv/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/sv/substreams/sps/sps-faq.mdx b/website/pages/sv/substreams/sps/sps-faq.mdx deleted file mode 100644 index 294765705b96..000000000000 --- a/website/pages/sv/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Vanliga frågor om Substreams-drivna subgrafer ---- - -## Vad är Substreams? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -Gå till [Substreams Documentation](/substreams/introduction/) för att lära dig mer om Substreams. - -## Vad är Substreams-drivna subgrafer? - -[Substreams-drivna subgrafer](/subgraphs/cookbook/substreams-powered-subgraphs/) kombinerar kraften hos Substreams med subgrafiernas möjlighet att frågas. När en Substreams-driven subgraf publiceras kan datan som produceras av Substreams omvandlingar [utdata ändringar av enheter](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), vilket är kompatibelt med subgrafiernas enheter. - -Om du redan är bekant med utveckling av subgrafer kan du notera att Substreams-drivna subgrafer sedan kan frågas på samma sätt som om de hade producerats av AssemblyScript omvandlingslagret, med alla fördelar med subgrafer, som att tillhandahålla en dynamisk och flexibel GraphQL API. - -## Hur skiljer sig Substreams-drivna subgrafer från subgrafer? - -Subgrafer består av datakällor som specificerar händelser på blockkedjan och hur dessa händelser ska omvandlas via hanterare skrivna i AssemblyScript. Dessa händelser bearbetas sekventiellt, baserat på ordningen som händelserna inträffar på blockkedjan. - -Å andra sidan har Substreams-drivna subgrafer en enda datakälla som refererar till ett Substreams-paket, vilket bearbetas av Graph Node. Substreams har tillgång till ytterligare detaljerade on-chain data jämfört med konventionella subgrafer och kan även dra nytta av massivt parallell bearbetning, vilket kan leda till betydligt snabbare bearbetningstider. - -## Vilka fördelar har användning av Substreams-drivna subgrafer? - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## Vilka fördelar har Substreams? - -Det finns många fördelar med att använda Substreams, inklusive: - -- Sammansättbarhet: Du kan stapla Substreams-moduler som LEGO-block och bygga på gemenskapsmoduler för att ytterligare förädla offentliga data. - -- Högpresterande indexering: Ordervärden snabbare indexering genom storskaliga kluster av parallella operationer (tänk BigQuery). - -- Utdata var som helst: Du kan sänka dina data var som helst du vill: PostgreSQL, MongoDB, Kafka, subgrafer, platta filer, Google Sheets. - -- Programmerbarhet: Använd kod för att anpassa extrahering, utföra transformationsbaserade aggregeringar och modellera din utdata för flera sänkar. - -- Tillgång till ytterligare data som inte är tillgänglig som en del av JSON RPC - -- Alla fördelar med Firehose. - -## Vad är Firehose? - -Utvecklat av [StreamingFast](https://www.streamingfast.io/), är Firehose ett blockkedjedata-extraktionslager som är utformat från grunden för att bearbeta blockkedjans fullständiga historik med hastigheter som tidigare inte var skådade. Genom att erbjuda en filbaserad och strömningsorienterad metod är det en kärnkomponent i StreamingFasts svit med öppen källkodstekniker och grunden för Substreams. - -Gå till [documentation](https://firehose.streamingfast.io/) för att lära dig mer om Firehose. - -## Vilka fördelar har Firehose? - -Det finns många fördelar med att använda Firehose, inklusive: - -- Lägsta latens och ingen avfrågning: I en strömningsorienterad stil är Firehose-noderna utformade för att snabbt skicka ut blockdata. - -- Förebygger driftstopp: Designat från grunden för hög tillgänglighet. - -- Missa aldrig en händelse: Firehose-strömmens markör är utformad för att hantera gafflar och att fortsätta där du avslutade under alla förhållanden. - -- Rikaste datamodell:  Bästa datamodell som inkluderar balansändringar, hela anropsträdet, interna transaktioner, loggar, lagringsändringar, gasavgifter och mer. - -- Använder platta filer: Blockkedjedata extraheras till platta filer, den billigaste och mest optimerade datorkällan som finns tillgänglig. - -## Var kan utvecklare få mer information om Substreams-drivna subgrafer och Substreams? - -[Substreams-dokumentationen](/substreams/introduction/) kommer att lära dig hur du bygger Substreams-moduler. - -[Substreams-drivna subgrafer dokumentationen](/subgraphs/cookbook/substreams-powered-subgraphs/) kommer att visa dig hur man paketerar dem för distribution på The Graph. - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## Vad är rollen för Rust-moduler i Substreams? - -Rust-moduler är motsvarigheten till AssemblyScript-mappers i subgrafer. De kompileras till WASM på ett liknande sätt, men programmeringsmodellen tillåter parallell körning. De definierar vilken typ av omvandlingar och aggregeringar du vill tillämpa på råblockkedjedata. - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## Vad gör Substreams sammansättbart? - -Vid användning av Substreams sker sammansättningen på omvandlingsnivån, vilket gör att cachade moduler kan återanvändas. - -Som exempel kan Alice bygga en DEX-prismodul, Bob kan använda den för att bygga en volymaggregator för vissa intressanta tokens, och Lisa kan kombinera fyra individuella DEX-prismoduler för att skapa en prisoracle. En enda Substreams-begäran kommer att paketera alla dessa individuella moduler, länka dem samman, för att erbjuda en mycket mer förädlad dataström. Den strömmen kan sedan användas för att fylla i en subgraf och frågas av användare. - -## Hur kan man bygga och distribuera en Substreams-drivna subgraf? - -Efter att ha [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) en Substreams-drivna subgraf kan du använda Graph CLI för att distribuera den i [Subgraph Studio](https://thegraph.com/studio/). - -## Var kan jag hitta exempel på Substreams och Substreams-drivna subgrafer? - -Du kan besöka [detta Github-repo](https://github.com/pinax-network/awesome-substreams) för att hitta exempel på Substreams och Substreams-drivna subgrafer. - -## Vad innebär Substreams och Substreams-drivna subgrafer för The Graph Network? - -Integrationen lovar många fördelar, inklusive extremt högpresterande indexering och ökad sammansättbarhet genom att dra nytta av gemenskapsmoduler och bygga vidare på dem. diff --git a/website/pages/sv/substreams/sps/triggers.mdx b/website/pages/sv/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/sv/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/sv/substreams/sps/tutorial.mdx b/website/pages/sv/substreams/sps/tutorial.mdx deleted file mode 100644 index 8140015d7721..000000000000 --- a/website/pages/sv/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Förutsättningar - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/sw/sps/_meta.js b/website/pages/sw/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/sw/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/sw/sps/introduction.mdx b/website/pages/sw/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/sw/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/sw/sps/sps-faq.mdx b/website/pages/sw/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/sw/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/sw/sps/triggers.mdx b/website/pages/sw/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/sw/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/sw/sps/tutorial.mdx b/website/pages/sw/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/sw/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/sw/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/sw/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/sw/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/sw/substreams/developing/_meta.js b/website/pages/sw/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/sw/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/sw/substreams/developing/devcontainer.mdx b/website/pages/sw/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/sw/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/sw/substreams/developing/sinks/_meta.js b/website/pages/sw/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/sw/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/sw/substreams/developing/sinks/sinks.mdx b/website/pages/sw/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/sw/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/sw/substreams/developing/solana/_meta.js b/website/pages/sw/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/sw/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/sw/substreams/developing/solana/accountchanges.mdx b/website/pages/sw/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/sw/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/sw/substreams/developing/solana/solana.mdx b/website/pages/sw/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/sw/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/sw/substreams/developing/solana/transactions.mdx b/website/pages/sw/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/sw/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/sw/substreams/getting-started-substreams.mdx b/website/pages/sw/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/sw/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/sw/substreams/introduction.mdx b/website/pages/sw/substreams/introduction.mdx new file mode 100644 index 000000000000..25fcfa5a5c2c --- /dev/null +++ b/website/pages/sw/substreams/introduction.mdx @@ -0,0 +1,44 @@ +--- +title: Introduction to Substreams +--- + +![Substreams Logo](/img/substreams-logo.png) + +To start coding right away, check out the [Substreams Quick Start](/substreams/getting-started-substreams/). + +## Overview + +Substreams is a powerful parallel blockchain indexing technology designed to enhance performance and scalability within The Graph Network. + +## Substreams Capabilities + +- **Accelerated Indexing**: Boost subgraph indexing time with a parallelized engine for quicker data retrieval and processing. +- **Multi-Chain Support**: Expand indexing capabilities beyond EVM-based chains, supporting ecosystems like Solana, Injective, Starknet, and Vara. +- **Enhanced Data Model**: Access comprehensive data, including the `trace` level data on EVM or account changes on Solana, while efficiently managing forks/disconnections. +- **Multi-Sink Support:** For Subgraph, Postgres database, Clickhouse, and Mongo database. + +## How Substreams Works in 4 Steps + +1. You write a Rust program, which defines the transformations that you want to apply to the blockchain data. For example, the following Rust function extracts relevant information from an Ethereum block (number, hash, and parent hash). + +```rust +fn get_my_block(blk: Block) -> Result { + let header = blk.header.as_ref().unwrap(); + + Ok(MyBlock { + number: blk.number, + hash: Hex::encode(&blk.hash), + parent_hash: Hex::encode(&header.parent_hash), + }) +} +``` + +2. You wrap up your Rust program into a WASM module just by running a single CLI command. + +3. The WASM container is sent to a Substreams endpoint for execution. The Substreams provider feeds the WASM container with the blockchain data and the transformations are applied. + +4. You select a [sink](https://docs.substreams.dev/how-to-guides/sinks), a place where you want to send the transformed data (for example a SQL database or a Subgraph). + +## Additional Resources + +All Substreams developer documentation is maintained by the StreamingFast core development team on the [Substreams registry](https://docs.substreams.dev). diff --git a/website/pages/sw/substreams/pubsubstreams.mdx b/website/pages/sw/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/sw/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/sw/substreams/sps/_meta.js b/website/pages/sw/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/sw/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/sw/substreams/sps/introduction.mdx b/website/pages/sw/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/sw/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/sw/substreams/sps/triggers.mdx b/website/pages/sw/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/sw/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/sw/substreams/sps/tutorial.mdx b/website/pages/sw/substreams/sps/tutorial.mdx deleted file mode 100644 index bb278b7f0eee..000000000000 --- a/website/pages/sw/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Prerequisites - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/tr/sps/_meta.js b/website/pages/tr/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/tr/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/tr/sps/introduction.mdx b/website/pages/tr/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/tr/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/tr/sps/sps-faq.mdx b/website/pages/tr/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/tr/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/tr/sps/triggers.mdx b/website/pages/tr/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/tr/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/tr/sps/tutorial.mdx b/website/pages/tr/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/tr/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/tr/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/tr/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index fd53fae19940..000000000000 --- a/website/pages/tr/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams destekli subgraphlar ---- - -[Substreams](/substreams/introduction/), Graph Ağı için StreamingFast tarafından geliştirilen bir blok zinciri verileri işleme çerçevesidir. Bir substreams modülü, subgraph varlıklarıyla uyumlu olan varlık değişiklikleri çıktısı verebilir. Bir subgraph, böyle bir Substreams modülünü veri kaynağı olarak kullanabilir ve Substreams'in indeksleme hızını ve ek verilerini subgraph geliştiricilere kazandırabilir. - -## Gereksinimler - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Cookbook'u edinin - -> Bu rehber, bu [Substreams destekli subgraph'ı referans](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph) olarak kullanmaktadır. - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Bir Substreams paketi tanımlama - -Bir Substreams paketi tiplerden ([Protocol Buffers](https://protobuf.dev/) olarak tanımlanmış olanlar), modüllerden (Rust dilinde yazılmış), tiplere referans veren ve modüllerin nasıl tetikleneceğini belirten bir `substreams.yaml` dosyasından oluşur. [Substreams geliştirme hakkında daha fazla bilgi edinmek için Substreams dökümantasyonunu ziyaret edin](/substreams/introduction/) ve daha fazla örnek için [awesome-substreams](https://github.com/pinax-network/awesome-substreams) ve [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) sayfalarına göz atın. - -Bahsi geçen Substreams paketi, Ethereum Ana Ağı'nda kontrat dağıtımlarını algılar ve yeni oluşturulan kontratlar için oluşturma bloğunu ve zaman damgasını takip eder. Bunun için `/proto/example.proto` içinde buna özel bir `Contract` türü bulunmaktadır ([Protokol Buffers tanımlama hakkında daha fazla bilgi edinin](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -Substreams paketinin temel mantığı, her bloğu işleyen, Create çağrıları için bir filtreleme yapan ve geri dönüş olarak `Contracts` verisini döndüren `lib.rs` içindeki bulunan `map_contract` modülüdür: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -Bir Substreams paketi, uyumlu varlık değişiklikleri üreten bir modüle sahip olduğu sürece bir subgraph tarafından kullanılabilir. Örnek Substreams paketi, `lib.rs` dosyasında ek bir `graph_out` modülüne sahiptir ve Graph Düğümü tarafından işlenebilen `substreams_entity_change::pb::entity::EntityChanges` çıktısını döndürür. - -> `substreams_entity_change` paketi ayrıca varlık değişiklikleri oluşturmak için özel bir `Tables` işlevine sahiptir ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). Oluşturulan Varlık Değişiklikleri, buna karşılık gelen subgraph'ın `subgraph.graphql` dosyasında tanımlanan `schema.graphql` varlıklarıyla uyumlu olmalıdır. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -Bu türler ve modüller `substreams.yaml` dosyasında bir araya getirilir: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -`substreams graph` komutunu çalıştırarak bir Bloktan `map_contract`'a ve ardından `graph_out`'a genel "akışı" kontrol edebilirsiniz: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -Bu Substreams paketini bir subgraph tarafından kullanılmak üzere hazırlamak için aşağıdaki komutları çalıştırmanız gerekir: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> Substreams komutlarının temelini anlamak isterseniz, bu komutlar, `package.json` dosyasında tanımlanmıştır - -Bu,`substreams.yaml` dosyasındaki paket adı ve sürümden hareketle bir `spkg` dosyası oluşturur. `spkg` dosyası, Graph Düğümü'nün bu Substreams paketini alabilmesi için gereken tüm bilgilere sahiptir. - -> Substreams paketini güncellerseniz, yaptığınız değişikliklere bağlı olarak `spkg`'yı güncel tutmak için yukarıdaki komutların bazılarını veya tümünü çalıştırmanız gerekebilir. - -## Substreams Destekli Bir Subgraph Tanımlama - -Substreams destekli subgraphlar yeni bir veri kaynağı türü('kind') olan "substreams"'i sunar. Bu tür subgraphlar yalnızca bir veri kaynağına sahip olabilir. - -Bu veri kaynağı indekslenen ağı, Substreams paketi (`spkg`) olarak ilgili bir dosya konumu ve Substreams paketinin subgraph uyumlu varlık değişiklikleri üreten modülü belirtmelidir (bu durumda yukarıdaki Substreams paketinden `map_entity_changes`). Eşleştirme belirtilmiştir, fakat yalnızca eşleştirme türünü ("substreams/graph-entities") ve apiVersion'ı tanımlar. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -`subgraph.yaml` dosyası ayrıca bir şema dosyasına referans verir. Bu dosyanın gereksinimleri değişmemiş olmasına rağmen, `subgraph.yaml` içinde referans verilen Substreams modülü tarafından üretilen varlık değişiklikleriyle uyumlu olmalıdır. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Yukarıdakiler verildiğinde, subgraph geliştiricileri Graph CLI kullanarak bu Substreams destekli subgraph'ı dağıtabilir. - -> Ethereum Ana Ağını indeksleyen Substreams destekli subgraphlar, [Subgraph Stüdyo'ya](https://thegraph.com/studio/) dağıtılabilir. - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -Bu kadar! Bir Substreams destekli subgraph oluşturup dağıttınız. - -## Substreams destekli subgraphlar'ın sunulması - -Substreams destekli subgraphlar'ı sunabilmek için Graph Düğümü'nün ilgili ağ için bir Substreams sağlayıcısı ve zincir başını takip etmek için bir Firehose veya RPC yapılandırılması gerekmektedir. Bu sağlayıcılar, bir `config.toml` dosyası aracılığıyla yapılandırılabilir: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/tr/substreams/developing/_meta.js b/website/pages/tr/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/tr/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/tr/substreams/developing/devcontainer.mdx b/website/pages/tr/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/tr/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/tr/substreams/developing/sinks/_meta.js b/website/pages/tr/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/tr/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/tr/substreams/developing/sinks/sinks.mdx b/website/pages/tr/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/tr/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/tr/substreams/developing/solana/_meta.js b/website/pages/tr/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/tr/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/tr/substreams/developing/solana/accountchanges.mdx b/website/pages/tr/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/tr/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/tr/substreams/developing/solana/solana.mdx b/website/pages/tr/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/tr/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/tr/substreams/developing/solana/transactions.mdx b/website/pages/tr/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/tr/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/tr/substreams/getting-started-substreams.mdx b/website/pages/tr/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/tr/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/tr/substreams/pubsubstreams.mdx b/website/pages/tr/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/tr/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/tr/substreams/sps/_meta.js b/website/pages/tr/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/tr/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/tr/substreams/sps/introduction.mdx b/website/pages/tr/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/tr/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/tr/substreams/sps/sps-faq.mdx b/website/pages/tr/substreams/sps/sps-faq.mdx deleted file mode 100644 index b6127a7808b8..000000000000 --- a/website/pages/tr/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Substreams destekli subgraphlar SSS ---- - -## Substreams nedir? - -[StreamingFast](https://www.streamingfast.io/) tarafından geliştirilen Substreams, zengin blokzinciri veri akışlarını işleyebilen son derece güçlü bir işlem motorudur. Substreams, blokzinciri verilerini son kullanıcı uygulamaları tarafından hızlı ve sorunsuz bir şekilde işlenmek üzere rafine etmenizi ve şekillendirmenizi sağlar. Daha spesifik olmak gerekirse, Substreams, farklı blokzincirleriyle uyumlu, paralelleştirilmiş ve akış öncelikli bir motor olup bir blokzinciri veri dönüşüm katmanı olarak işlev görür. [Firehose](https://firehose.streamingfast.io/) tarafından desteklenen Substreams, geliştiricilerin Rust modülleri yazmasına, topluluk modüllerini kullanarak geliştirme yapmasına, son derece yüksek performanslı endeksleme sağlamasına ve verilerini herhangi bir yere yönlendirmesine ([sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink)) olanak tanır. - -Substreams hakkında daha fazla bilgi için [SubstreamsDökümantasyonuna](/substreams/introduction/) gidin. - -## Substreams destekli subgraphlar nelerdir? - -[Substreams destekli subgraphlar](/subgraphs/cookbook/substreams-powered-subgraphs/), Substreams'in gücünü subgraphlar'ın sorgulanabilirliği ile birleştirir. Substreams ile desteklenen bir subgraph yayınladığınızda, Substreams dönüşümleri tarafından üretilen veriler, subgraph varlıkları ile uyumlu olan [varlık değişikliklerini çıktı](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) olarak verebilir. - -Eğer subgraph geliştirme konusun aşina iseniz, aklınızda bulundurun ki, Substreams destekli subgraphlar AssemblyScript dönüştürme katmanı tarafından üretilmiş gibi sorgulanabilir ve dinamik ve esnek bir GraphQL API sağlayarak Subgraph avantajlarından yararlanabilir. - -## Substreams destekli subgraphlar'ın normal subgraphlar'dan farkı nedir? - -Subgraphlar, zincir üstü olayları ve bu olayların nasıl AssemblyScript işleyicileri aracılığıyla dönüştürüleceğini belirleyen veri kaynaklarından oluşur. Bu olaylar, olayların zincir üstünde meydana geldikleri sıraya göre işlenir. - -Buna karşılık, Substreams destekli subgraphlar, Substreams paketini referans alan tek bir veri kaynağına sahiptir ve bu veri kaynağı Graph Düğümü tarafından işlenir. Substreams, geleneksel subgraphlara kıyasla daha detaylı zincir üstü verilere erişebilir ve ayrıca büyük ölçekli paralel işlemden yararlanarak çok daha hızlı işleme süreleri elde edebilir. - -## Substreams destekli subgraphlar kullanmanın avantajları nelerdir? - -Substreams destekli subgraph'ler, Substreams'in tüm avantajlarını subgraph'lerin sorgulanabilirliğiyle birleştirir. Bu yaklaşım, The Graph'e daha fazla birleştirilebilirlik ve yüksek performanslı endeksleme sağlar. Ayrıca, yeni veri kullanım senaryolarını mümkün kılar. Örneğin, Substreams destekli subgraph'inizi oluşturduktan sonra, [Substreams modüllerinizi](https://substreams.streamingfast.io/documentation/develop/manifest-modules) PostgreSQL, MongoDB ve Kafka gibi farklı [veri hedeflerine](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) çıktı almak için yeniden kullanabilirsiniz. - -## Substreams'in faydaları nelerdir? - -Substreams kullanmanın birçok faydası vardır, bunlar şunlardır: - -- Birleştirilebilir: Substreams modüllerini LEGO blokları gibi birleştirebilir ve topluluk modüllerine dayanarak açık verileri daha da ayrıntılayabilirsiniz. - -- Yüksek performanslı indeksleme: Büyük ölçekli paralel işlemler sayesinde sıradan işlemlere göre onlarca kat daha hızlı indeksleme sağlar (BigQuery gibi). - -- Her yere veri gönderme: Verilerinizi PostgreSQL, MongoDB, Kafka, subgraphlar, düz dosyalar, Google Sheets gibi herhangi bir yere gönderebilirsiniz. - -- Programlanabilir: Kod kullanarak çıkarma işlemlerini özelleştirmek, dönüşüm zamanında toplamalar yapmak ve çıktınızı birden çok hedef için modelleyebilirsiniz. - -- JSON RPC'nin parçası olmayan ek verilere erişim sağlar - -- Firehose'un tüm faydalarından yararlanır. - -## Firehose nedir? - -[StreamingFast](https://www.streamingfast.io/) tarafından geliştirilen Firehose, daha önce görülmemiş hızlarda blok zincirinin baştan sona, tam geçmişini işlemek için tasarlanmış bir blok zinciri veri çıkarma katmanıdır. Dosya tabanlı ve akışa odaklı bir yaklaşım sunarak, StreamingFast'in açık kaynaklı teknolojilerinin temel bileşenlerinden biridir ve Substreamler'in temelini oluşturur. - -Firehose hakkında daha fazla bilgi için [documentation](https://firehose.streamingfast.io/) gidin. - -## Firehose'un faydaları nelerdir? - -Firehose kullanmanın birçok faydası vardır, bunlar şunlardır: - -- En düşük gecikme ve sorgulama yok: Akışa odaklı bir şekilde, Firehose düğümleri blok verilerini ilk olarak dışarıya göndermek üzere tasarlanmıştır. - -- Kesintisiz çalışma: Yüksek Erişilebilirlik için baştan sona tasarlanmıştır. - -- Hiçbir şeyi kaçırmaz: Firehose akış imleci, fork durumlarını ele almak ve herhangi bir durumda kaldığınız yerden devam etmek için tasarlanmıştır. - -- En zengin veri modeli: Bakiye değişikliklerini, tam çağrı ağacını, dahili işlemleri, kayıtları, depolama değişikliklerini, gaz maliyetlerini ve daha fazlasını içeren en iyi veri modeli. - -- Düz dosyalardan yararlanma: Blok zinciri verileri düz dosyalara çıkarılır, en ucuz ve en optimize hesaplama kaynağı kullanılır. - -## Geliştiriciler, Substreams destekli subgraphlar ve Substreams hakkında daha fazla bilgiye nereden erişebilir geliştiriciler? - -[Substreams dökümantasyonu](/substreams/introduction/), Substreams modülleri nasıl oluşturulacağını öğretecektir. - -[Substreams destekli subgrahplar belgeleri](/subgraphs/cookbook/substreams-powered-subgraphs/), onları Graph üzerinde dağıtmak için nasıl paketleyeceğinizi gösterecektir. - -[En son sürüm Substreams Codegen aracı](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6), hiç kod yazmadan bir Substreams projesi başlatmanıza olanak tanır. - -## Rust modüllerinin Substreams içindeki rolü nedir? - -Rust modülleri, Subgraphs'teki AssemblyScript eşleştiricilerinin karşılığıdır. WASM'ye benzer şekilde derlenirler, ancak programlama modelleri paralel yürütme için olanak sağlar. Rust modülleri, ham blok zinciri verilerine uygulamak istediğiniz dönüşümleri ve birleştirmeleri tanımlar. - -Detaylar için [modüller dokümantasyonuna](https://substreams.streamingfast.io/documentation/develop/manifest-modules) bakın. - -## Substreams'i birleştirilebilir yapan nedir? - -Substream kullanırken, kompozisyon dönüşüm katmanında gerçekleşir ve önbelleğe alınmış modüllerin tekrar kullanılmasına olanak sağlar. - -Örnek olarak, Alice bir merkeziyetsiz borsa fiyat modülü oluşturabilir, Bob ilgisini çeken bazı tokenler için bir hacim aggregator inşa edebilir ve Lisa dört bireysel merkeziyetsiz borsa fiyat modülünü bir araya getirerek bir fiyat oracle'ı oluşturabilir. Tek bir Substreams talebi, tüm bu bireylerin modüllerini bir araya getirir, birleştirir ve çok daha sofistike bir veri akışı sunar. Bu akış daha sonra bir subgraph'ı doldurmak ve tüketiciler tarafından sorgulanmak için kullanılabilir. - -## Bir Substreams destekli Subgraph nasıl oluşturulur ve dağıtılır? - -Bir Substreams destekli Subgraph [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) sonra, onu [Subgraph Stüdyo](https://thegraph.com/studio/) üzerinde dağıtmak için Graph CLI'yi kullanabilirsiniz. - -## Substreams ve Substreams destekli subgraphlar ile ilgili örnekleri nerede bulubilirim? - -Substreams ve Substreams destekli subgraphlar ile ilgili örnekleri bulmak için [bu Github deposunu](https://github.com/pinax-network/awesome-substreams) ziyaret edebilirsiniz. - -## Substreams ve Substreams destekli subgraphlar, Graph Ağı için ne anlam ifade etmektedir? - -Bu entegrasyon, topluluk modüllerinden yararlanarak son derece yüksek performanslı indeksleme ve daha fazla birleştirme yapma avantajları sunar. diff --git a/website/pages/tr/substreams/sps/triggers.mdx b/website/pages/tr/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/tr/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/tr/substreams/sps/tutorial.mdx b/website/pages/tr/substreams/sps/tutorial.mdx deleted file mode 100644 index 219363637aaa..000000000000 --- a/website/pages/tr/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Ön Koşullar - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/uk/sps/_meta.js b/website/pages/uk/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/uk/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/uk/sps/introduction.mdx b/website/pages/uk/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/uk/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/uk/sps/sps-faq.mdx b/website/pages/uk/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/uk/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/uk/sps/triggers.mdx b/website/pages/uk/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/uk/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/uk/sps/tutorial.mdx b/website/pages/uk/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/uk/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/uk/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/uk/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/uk/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/uk/substreams/developing/_meta.js b/website/pages/uk/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/uk/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/uk/substreams/developing/devcontainer.mdx b/website/pages/uk/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/uk/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/uk/substreams/developing/sinks/_meta.js b/website/pages/uk/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/uk/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/uk/substreams/developing/sinks/sinks.mdx b/website/pages/uk/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/uk/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/uk/substreams/developing/solana/_meta.js b/website/pages/uk/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/uk/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/uk/substreams/developing/solana/accountchanges.mdx b/website/pages/uk/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/uk/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/uk/substreams/developing/solana/solana.mdx b/website/pages/uk/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/uk/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/uk/substreams/developing/solana/transactions.mdx b/website/pages/uk/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/uk/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/uk/substreams/getting-started-substreams.mdx b/website/pages/uk/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/uk/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/uk/substreams/pubsubstreams.mdx b/website/pages/uk/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/uk/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/uk/substreams/sps/_meta.js b/website/pages/uk/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/uk/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/uk/substreams/sps/introduction.mdx b/website/pages/uk/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/uk/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/uk/substreams/sps/sps-faq.mdx b/website/pages/uk/substreams/sps/sps-faq.mdx deleted file mode 100644 index ec24f97300ae..000000000000 --- a/website/pages/uk/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Substreams-powered subgraphs FAQ ---- - -## What are Substreams? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. - -## What are Substreams-powered subgraphs? - -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. - -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. - -## How are Substreams-powered subgraphs different from subgraphs? - -Subgraphs are made up of datasources which specify on-chain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen on-chain. - -By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular on-chain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. - -## What are the benefits of using Substreams-powered subgraphs? - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## What are the benefits of Substreams? - -There are many benefits to using Substreams, including: - -- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. - -- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). - -- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. - -- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. - -- Access to additional data which is not available as part of the JSON RPC - -- All the benefits of the Firehose. - -## What is the Firehose? - -Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. - -Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. - -## What are the benefits of the Firehose? - -There are many benefits to using Firehose, including: - -- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. - -- Prevents downtimes: Designed from the ground up for High Availability. - -- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. - -- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. - -- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. - -## Where can developers access more information about Substreams-powered subgraphs and Substreams? - -The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. - -The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## What is the role of Rust modules in Substreams? - -Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## What makes Substreams composable? - -When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. - -As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. - -## How can you build and deploy a Substreams-powered Subgraph? - -After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). - -## Where can I find examples of Substreams and Substreams-powered subgraphs? - -You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. - -## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? - -The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/uk/substreams/sps/triggers.mdx b/website/pages/uk/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/uk/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/uk/substreams/sps/tutorial.mdx b/website/pages/uk/substreams/sps/tutorial.mdx deleted file mode 100644 index bb278b7f0eee..000000000000 --- a/website/pages/uk/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Prerequisites - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/ur/sps/_meta.js b/website/pages/ur/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/ur/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ur/sps/introduction.mdx b/website/pages/ur/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/ur/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/ur/sps/sps-faq.mdx b/website/pages/ur/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/ur/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/ur/sps/triggers.mdx b/website/pages/ur/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/ur/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/ur/sps/tutorial.mdx b/website/pages/ur/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/ur/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/ur/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/ur/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 7c3cdda1b99a..000000000000 --- a/website/pages/ur/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: سب سٹریمز سے چلنے والے سب گرافس ---- - -[Substreams](/سب سٹریمز/) بلاکچین ڈیٹا کی پروسیسنگ کے لیے ایک نیا فریم ورک ہے، جسے سٹریمنگ فاسٹ نے گراف نیٹ ورک کے لیے تیار کیا ہے۔ سب سٹریمز کے ماڈیولز ہستی کی تبدیلیوں کو آؤٹ پٹ کر سکتے ہیں، جو سب گراف اداروں کے ساتھ ہم آہنگ ہیں۔ ایک سب گراف اس طرح کے سب سٹریمز ماڈیول کو ڈیٹا سورس کے طور پر استعمال کر سکتا ہے، جس سے انڈیکسنگ کی رفتار اور سب سٹریمز کا اضافی ڈیٹا سب گراف ڈویلپرز تک پہنچ جاتا ہے. - -## تقاضے - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## کک بک حاصل کریں - -> یہ کک بک اس [سب اسٹریم سے چلنے والے سب گراف کو بطور حوالہ استعمال کرتی ہے](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## سب سٹریمز پیکیج کی وضاحت کرنا - -ایک سب سٹریمز پیکیج اقسام پر مشتمل ہے (جس کی وضاحت [پروٹوکول بفرز](https://protobuf.dev/))، ماڈیولز (Rust میں لکھی گئی ہے)، اور ایک `substreams.yaml` فائل جو اقسام کا حوالہ دیتی ہے، اور یہ بتاتی ہے کہ ماڈیول کیسے ہیں متحرک ہیں. [سب سٹریمز ڈویلپمنٹ کے بارے میں مزید جاننے کے لیے سب سٹریمز کی دستاویزات دیکھیں](/substreams/introduction/)، اور [wesome-substreams](https://github.com/pinax-network/awesome-substreams) اور [Substreams cookbook](https مزید مثالوں کے لیے://github.com/pinax-network/substreams-cookbook). - -زیر بحث سب اسٹریمز پیکیج مینیٹ ایتھیریم پر کنٹریکٹ کی تعیناتیوں کا پتہ لگاتا ہے، تمام نئے تعینات کردہ کنٹریکٹس کے لیے تخلیق بلاک اور ٹائم اسٹیمپ کا پتہ لگاتا ہے۔ ایسا کرنے کے لیے، `/proto/example.proto` ([پروٹوکول بفرز کی تعریف کرنے کے بارے میں مزید جانیں](https://protobuf.dev/programming-guides/proto3/#simple)) میں ایک مخصوص `Contract` قسم ہے: - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -سب اسٹریمز پیکج کی بنیادی منطق `lib.rs` میں ایک `map_contract` ماڈیول ہے، جو ہر بلاک پر کارروائی کرتا ہے، ایسی کالز تخلیق کرنے کے لئے فلٹر کرتا ہے جو واپس نہیں آتیں، `Contracts` واپس کرتی ہیں: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -سب اسٹریمز پیکیج کو سب گراف کے ذریعہ استعمال کیا جاسکتا ہے جب تک کہ اس میں ایک ماڈیول موجود ہو جو ہم آہنگ ہستی کی تبدیلیوں کو آؤٹ پٹ کرتا ہے۔ مثال کے سب سٹریمز پیکیج میں `lib.rs` میں ایک اضافی `graph_out` ماڈیول ہے جو `substreams_entity_change::pb::entity::EntityChanges` آؤٹ پٹ لوٹاتا ہے، جس پر گراف نوڈ کے ذریعے کارروائی کی جا سکتی ہے. - -> 'substreams_entity_change' کریٹ میں صرف ہستی کی تبدیلیاں پیدا کرنے کے لیے ایک وقف کردہ 'Tables' فنکشن ہے ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). تخلیق کردہ ہستی کی تبدیلیاں متعلقہ سب گراف کے `subgraph.graphql` میں بیان کردہ `schema.graphql` اداروں کے ساتھ ہم آہنگ ہونی چاہئیں. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -ان اقسام اور ماڈیولز کو `substreams.yaml` میں ایک ساتھ کھینچا جاتا ہے: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -آپ 'سب اسٹریمز گراف' کو چلا کر ایک بلاک سے `map_contract` سے `graph_out` تک مجموعی طور پر "فلو" کو چیک کر سکتے ہیں: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -سب اسٹریمز کے ذریعے استعمال کے لیے اس سب اسٹریم پیکیج کو تیار کرنے کے لیے، آپ کو درج ذیل کمانڈز چلانے چاہئیں: - -```bash -yarn substreams:protogen # /src/pb میں قسمیں تیار کرتا ہے -yarn substreams:build # سب سٹریمز بناتا ہے -yarn substreams:package # سب اسٹریمز کو .spkg فائل میں پیک کرتا ہے - -# متبادل طور پر، یارن سب سٹریمز: مندرجہ بالا تمام کمانڈز کو کالز تیار کریں -``` - -> ان اسکرپٹس کی وضاحت `package.json` فائل میں کی گئی ہے اگر آپ بنیادی سب سٹریمز کی کمانڈ کو سمجھنا چاہتے ہیں - -یہ 'substreams.yaml' سے پیکیج کے نام اور ورژن کی بنیاد پر ایک `spkg` فائل تیار کرتا ہے۔ `spkg` فائل میں وہ تمام معلومات ہیں جن کی گراف نوڈ کو اس سب سٹریمز پیکیج کو ہضم کرنے کی ضرورت ہے. - -> اگر آپ سب اسٹریم پیکج کو اپ ڈیٹ کرتے ہیں تو، آپ کی تبدیلیوں پر منحصر ہے، آپ کو مندرجہ بالا کچھ یا سبھی کمانڈز چلانے کی ضرورت پڑسکتی ہے تاکہ `spkg` اپ ٹو ڈیٹ رہے. - -## سب اسٹریمز سے چلنے والے سب گراف کی وضاحت کرنا - -سب اسٹریمز سے چلنے والے سب گرافس ڈیٹا کے ذریعہ کی ایک نئی `kind` متعارف کراتے ہیں، "سب اسٹریمز"۔ اس طرح کے سب گرافس میں صرف ایک ڈیٹا سورس ہو سکتا ہے. - -اس ڈیٹا سورس کو انڈیکسڈ نیٹ ورک، سب اسٹریم پیکیج (`spkg`) کو متعلقہ فائل لوکیشن کے طور پر اور اس سب اسٹریم پیکیج کے اندر موجود ماڈیول کی وضاحت کرنی چاہیے جو سب سٹریمز سے مطابقت رکھنے والی ہستی کی تبدیلیاں (اس صورت میں `map_entity_changes`، اوپر سب اسٹریمز پیکیج سے)۔ میپنگ کی وضاحت کی گئی ہے، لیکن صرف میپنگ کی قسم ("substreams/graph-entities") اور apiVersion کی شناخت کرتا ہے. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -`subgraph.yaml` ایک سکیما فائل کا بھی حوالہ دیتا ہے۔ اس فائل کے تقاضے غیر تبدیل شدہ ہیں، لیکن متعین کردہ ہستیوں کو `subgraph.yaml` میں حوالہ کردہ سب سٹریمز ماڈیول کے ذریعہ تیار کردہ ہستی کی تبدیلیوں کے ساتھ ہم آہنگ ہونا چاہئے. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -مندرجہ بالا کو دیکھتے ہوئے، سب گراف ڈویلپرز اس سب اسٹریمز سے چلنے والے سب گراف کو تعینات کرنے کے لیے گراف CLI استعمال کر سکتے ہیں. - -> سب اسٹریمز سے چلنے والے سب گرافس کو انڈیکس کرنے والے مین نیٹ ایتھیریم کو [سب گراف اسٹوڈیو](https://thegraph.com/studio/) میں تعینات کیا جا سکتا ہے. - -```bash -yarn install # graph-cli انسٹال کریں -yarn subgraph:build # سب گراف کی تعمیر کریں -yarn subgraph:deploy # سب گراف کو تعینات کریں -``` - -یہی ہے! آپ نے سب اسٹریمز سے چلنے والا سب گراف بنایا اور تعینات کیا ہے. - -## سب اسٹریمز سے چلنے والے سب گرافس کی خدمت کرنا - -سب اسٹریمز سے چلنے والے سب اسٹریمز کو پیش کرنے کے لیے، گراف نوڈ کو متعلقہ نیٹ ورک کے لیے سب اسٹریمز فراہم کنندہ کے ساتھ کنفیگر کیا جانا چاہیے، ساتھ ہی ساتھ چین ہیڈ کو ٹریک کرنے کے لیے فائر ہوز یا RPC کا ہونا چاہیے۔ ان فراہم کنندگان کو ایک `config.toml` فائل کے ذریعے ترتیب دیا جا سکتا ہے: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/ur/substreams/developing/_meta.js b/website/pages/ur/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/ur/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ur/substreams/developing/devcontainer.mdx b/website/pages/ur/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/ur/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/ur/substreams/developing/sinks/_meta.js b/website/pages/ur/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/ur/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ur/substreams/developing/sinks/sinks.mdx b/website/pages/ur/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/ur/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/ur/substreams/developing/solana/_meta.js b/website/pages/ur/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/ur/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/ur/substreams/developing/solana/accountchanges.mdx b/website/pages/ur/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/ur/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/ur/substreams/developing/solana/solana.mdx b/website/pages/ur/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/ur/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/ur/substreams/developing/solana/transactions.mdx b/website/pages/ur/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/ur/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/ur/substreams/getting-started-substreams.mdx b/website/pages/ur/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/ur/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/ur/substreams/pubsubstreams.mdx b/website/pages/ur/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/ur/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/ur/substreams/sps/_meta.js b/website/pages/ur/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/ur/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/ur/substreams/sps/introduction.mdx b/website/pages/ur/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/ur/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/ur/substreams/sps/sps-faq.mdx b/website/pages/ur/substreams/sps/sps-faq.mdx deleted file mode 100644 index 7434516e34b0..000000000000 --- a/website/pages/ur/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: سب اسٹریمز سے چلنے والے سب گرافس FAQ ---- - -## سب اسٹریمز کیا ہیں؟ - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -سب سٹریمز کے بارے میں مزید جاننے کے لیے [سب سٹریمز دستاویزات](/substreams/introduction/) پر جائیں. - -## سب سٹریمز سے چلنے والے سب گرافس کیا ہیں؟ - -[سب اسٹریمز سے چلنے والے سب گرافس](/subgraphs/cookbook/substreams-powered-subgraphs/)سب اسٹریمز کی طاقت کو سب گرافس کی کیوری کے ساتھ جوڑتا ہے۔ سب اسٹریمز سے چلنے والے سب گراف کو شائع کرتے وقت، سب سٹریمز کی تبدیلیوں سے تیار کردہ ڈیٹا، [آؤٹ پٹ ہستی میں تبدیلیاں](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs),کر سکتا ہے جو سب گراف اداروں کے ساتھ مطابقت رکھتا ہے. - -اگر آپ سب گراف ڈیولپمنٹ سے پہلے ہی واقف ہیں، تو نوٹ کریں کہ سب سٹریمز سے چلنے والے سب گرافس کے بارے میں کیوری کیا جا سکتا ہے، بالکل اسی طرح جیسے اسے اسمبلی اسکرپٹ ٹرانسفارمیشن لیئر کے ذریعے تیار کیا گیا ہو، جیسے کہ ایک متحرک اور لچکدار GraphQL API فراہم کرنا. - -## سب سٹریمز سے چلنے والے سب گرافس سب گراف سے کیسے مختلف ہیں؟ - -سب گرافس ڈیٹا سورسز پر مشتمل ہوتے ہیں جو آن چین ایونٹس کی وضاحت کرتے ہیں، اور ان واقعات کو اسمبلی اسکرپٹ میں لکھے گئے ہینڈلرز کے ذریعے کیسے تبدیل کیا جانا چاہیے۔ ان واقعات پر ترتیب وار کارروائی کی جاتی ہے، اس ترتیب کی بنیاد پر جس میں ایونٹس آن چین ہوتے ہیں. - -اس کے برعکس، سب سٹریمز سے چلنے والے سب گرافس میں ایک واحد ڈیٹا سورس ہوتا ہے جو سب سٹریم پیکیج کا حوالہ دیتا ہے، جس پر گراف نوڈ کے ذریعے کارروائی کی جاتی ہے۔ روایتی سب گرافس کے مقابلے سب سٹریمز کو اضافی دانے دار آن چین ڈیٹا تک رسائی حاصل ہے، اور یہ بڑے پیمانے پر متوازی پروسیسنگ سے بھی فائدہ اٹھا سکتے ہیں، جس کا مطلب بہت تیز پروسیسنگ کے اوقات ہو سکتا ہے. - -## سب سٹریمز سے چلنے والے سب گرافس استعمال کرنے کے کیا فوائد ہیں؟ - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## سب سٹریمز کے فوائد کہاں ہیں؟ - -سب سٹریمز کو استعمال کرنے کے بہت سے فوائد ہیں، بشمول: - -- کمپوز ایبل: آپ سب سٹریمز ماڈیولز جیسے LEGO بلاکس کو اسٹیک کر سکتے ہیں، اور عوامی ڈیٹا کو مزید بہتر کرتے ہوئے کمیونٹی ماڈیول بنا سکتے ہیں. - -- اعلی کارکردگی کی انڈیکسنگ: متوازی کارروائیوں کے بڑے پیمانے پر کلسٹرز کے ذریعے تیز تر انڈیکسنگ کے آرڈرز (سوچیں BigQuery). - -- کہیں بھی سینک: اپنے ڈیٹا کو جہاں چاہیں سینک: PostgreSQL، MongoDB، Kafka، سب گرافس، فلیٹ فائلز، Google Sheets. - -- قابل پروگرام: اسے اپنی مرضی کے مطابق بنانے کے لیے کوڈ کریں، دو ٹرانسفارم ٹائم ایگریگیشنز، اور متعدد حواس کے لیے اپنے آؤٹ پٹ کو ماڈل کریں. - -- اضافی ڈیٹا تک رسائی جو JSON RPC کے حصے کے طور پر دستیاب نہیں ہے - -- Firehose کے تمام فوائد. - -## Firehose کیا ہے؟ - -[StreamingFast](https://www.streamingfast.io/) کے ذریعے تیار کردہ، Firehose ایک بلاکچین ڈیٹا نکالنے کی پرت ہے جسے شروع سے بلاکچینز کی مکمل تاریخ کو اس رفتار سے پروسیس کرنے کے لیے ڈیزائن کیا گیا ہے جو پہلے نظر نہیں آتی تھیں۔ فائلوں پر مبنی اور سٹریمنگ فرسٹ اپروچ فراہم کرنا، یہ سٹریمنگ فاسٹ کے اوپن سورس ٹیکنالوجیز کے سوٹ کا بنیادی جزو اور سب اسٹریمز کی بنیاد ہے. - -Firehose کے بارے میں مزید جاننے کے لیے[documentation] (https://firehose.streamingfast.io/) پر جائیں. - -## Firehose کے کیا فوائد ہیں؟ - -Firehose استعمال کرنے کے بہت سے فوائد ہیں، بشمول: - -- سب سے کم تاخیر اور کوئی پولنگ نہیں: اسٹریمنگ کے پہلے انداز میں، Firehose نوڈس کو پہلے بلاک ڈیٹا کو آگے بڑھانے کی دوڑ کے لیے ڈیزائن کیا گیا ہے. - -- ڈاؤن ٹائمز کو روکتا ہے: اعلی دستیابی کے لیے زمین سے ڈیزائن کیا گیا ہے. - -- کبھی بھی بیٹ مت چھوڑیں: Firehose سٹریم کرسر کو فورکس ہینڈل کرنے اور کسی بھی حالت میں وہیں سے جاری رکھنے کے لیے بنایا گیا ہے جہاں آپ نے چھوڑا تھا. - -- امیرترین ڈیٹا ماڈل: بہترین ڈیٹا ماڈل جس میں بیلنس کی تبدیلیاں، مکمل کال ٹری، اندرونی ٹرانزیکشن، لاگز، اسٹوریج کی تبدیلیاں، گیس کی قیمتیں اور بہت کچھ شامل ہے. - -- فلیٹ فائلوں کا فائدہ اٹھاتا ہے: بلاکچین ڈیٹا کو فلیٹ فائلوں میں نکالا جاتا ہے، جو دستیاب سب سے سستا اور بہترین کمپیوٹنگ وسیلہ ہے. - -## ڈویلپرز سب سٹریمز سے چلنے والے سب گرافس اور سب سٹریمز کے بارے میں مزید معلومات کہاں تک رسائی حاصل کرسکتے ہیں؟ - -[سب سٹریمز دستاویزات](/substreams/introduction/) آپ کو سکھائے گا کہ سب سٹریمز کے ماڈیول کیسے بنائے جائیں. - -[سب سٹریمز سے چلنے والے سب گرافس کے دستاویزات](/subgraphs/cookbook/substreams-powered-subgraphs/) آپ کو دکھائے گا کہ انہیں گراف پر تعیناتی کے لیے کیسے پیک کیا جائے. - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## سب سٹریمز میں Rust ماڈیولز کا کیا کردار ہے؟ - -زنگ ماڈیول سب گراف میں اسمبلی اسکرپٹ میپرز کے مساوی ہیں۔ وہ اسی طرح WASM پر مرتب کیے گئے ہیں، لیکن پروگرامنگ ماڈل متوازی عمل درآمد کی اجازت دیتا ہے۔ وہ اس قسم کی تبدیلیوں اور مجموعوں کی وضاحت کرتے ہیں جسے آپ خام بلاکچین ڈیٹا پر لاگو کرنا چاہتے ہیں. - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## سب سٹریمز کو کمپوز ایبل کیا بناتا ہے؟ - -سب سٹریمز کا استعمال کرتے وقت، کمپوزیشن ٹرانسفارمیشن لیئر پر ہوتی ہے جو کیشڈ ماڈیولز کو دوبارہ استعمال کرنے کے قابل بناتی ہے. - -مثال کے طور پر، ایلس DEX پرائس ماڈیول بنا سکتی ہے، باب اپنی دلچسپی کے کچھ ٹوکنز کے لیے حجم ایگریگیٹر بنانے کے لیے اسے استعمال کر سکتا ہے، اور لیزا قیمت اوریکل بنانے کے لیے چار انفرادی DEX قیمت ماڈیول کو جوڑ سکتی ہے۔ ایک واحد سب سٹریمز کی درخواست ان تمام افراد کے ماڈیولز کو پیک کرے گی، ان کو آپس میں جوڑ دے گی، تاکہ ڈیٹا کا بہت زیادہ بہتر سلسلہ پیش کیا جا سکے۔ اس سلسلے کو پھر سب گراف کو آباد کرنے کے لیے استعمال کیا جا سکتا ہے، اور صارفین اس سے کیوریز کر سکتے ہیں. - -## آپ سب سٹریمز سے چلنے والے سب گراف کو کیسے بنا اور تعینات کر سکتے ہیں؟ - -سب سٹریمز سے چلنے والے سب گراف کی [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) کے بعد، آپ گراف CLI کو [Subgraph Studio](https://thegraph.com/studio/) میں تعینات کرنے کے لیے استعمال کر سکتے ہیں. - -## مجھے سب سٹریمز اور سب سٹریمز سے چلنے والے سب گرافس کی مثالیں کہاں مل سکتی ہیں؟ - -آپ سب سٹریمز اور سب سٹریم سے چلنے والے سب گرافس کی مثالیں تلاش کرنے کے لیے [یہ گٹ ہب ریپو](https://github.com/pinax-network/awesome-substreams) ملاحظہ کر سکتے ہیں. - -## گراف نیٹ ورک کے لیے سب سٹریمز اور سب سٹریمز سے چلنے والے سب گرافس کا کیا مطلب ہے؟ - -انضمام بہت سے فوائد کا وعدہ کرتا ہے، بشمول انتہائی اعلی کارکردگی کی انڈیکسنگ اور کمیونٹی ماڈیولز کا فائدہ اٹھا کر اور ان پر تعمیر کرنے کے ذریعے زیادہ کمپوز ایبلٹی. diff --git a/website/pages/ur/substreams/sps/triggers.mdx b/website/pages/ur/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/ur/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/ur/substreams/sps/tutorial.mdx b/website/pages/ur/substreams/sps/tutorial.mdx deleted file mode 100644 index eb250dc250c5..000000000000 --- a/website/pages/ur/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## شرطیں - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/vi/sps/_meta.js b/website/pages/vi/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/vi/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/vi/sps/introduction.mdx b/website/pages/vi/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/vi/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/vi/sps/sps-faq.mdx b/website/pages/vi/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/vi/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/vi/sps/triggers.mdx b/website/pages/vi/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/vi/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/vi/sps/tutorial.mdx b/website/pages/vi/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/vi/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/vi/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/vi/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 84e1b0adfd3b..000000000000 --- a/website/pages/vi/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Substreams-powered subgraphs ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## Requirements - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## Get the cookbook - -> This cookbook uses this [Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph). - -``` -graph init --from-example substreams-powered-subgraph -``` - -## Defining a Substreams package - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -The Substreams package in question detects contract deployments on Mainnet Ethereum, tracking the creation block and timestamp for all newly deployed contracts. To do this, there is a dedicated `Contract` type in `/proto/example.proto` ([learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -The core logic of the Substreams package is a `map_contract` module in `lib.rs`, which processes every block, filtering for Create calls which did not revert, returning `Contracts`: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -A Substreams package can be used by a subgraph as long as it has a module which outputs compatible entity changes. The example Substreams package has an additional `graph_out` module in `lib.rs` which returns a `substreams_entity_change::pb::entity::EntityChanges` output, which can be processed by Graph Node. - -> The `substreams_entity_change` crate also has a dedicated `Tables` function for simply generating entity changes ([documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html)). The Entity Changes generated must be compatible with the `schema.graphql` entities defined in the `subgraph.graphql` of the corresponding subgraph. - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -These types and modules are pulled together in `substreams.yaml`: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -You can check the overall "flow" from a Block, to `map_contract` to `graph_out` by running `substreams graph`: - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -To prepare this Substreams package for consumption by a subgraph, you must run the following commands: - -```bash -yarn substreams:protogen # generates types in /src/pb -yarn substreams:build # builds the substreams -yarn substreams:package # packages the substreams in a .spkg file - -# alternatively, yarn substreams:prepare calls all of the above commands -``` - -> These scripts are defined in the `package.json` file if you want to understand the underlying substreams commands - -This generates a `spkg` file based on the package name and version from `substreams.yaml`. The `spkg` file has all the information which Graph Node needs to ingest this Substreams package. - -> If you update the Substreams package, depending on the changes you make, you may need to run some or all of the above commands so that the `spkg` is up to date. - -## Defining a Substreams-powered subgraph - -Substreams-powered subgraphs introduce a new `kind` of data source, "substreams". Such subgraphs can only have one data source. - -This data source must specify the indexed network, the Substreams package (`spkg`) as a relative file location, and the module within that Substreams package which produces subgraph-compatible entity changes (in this case `map_entity_changes`, from the Substreams package above). The mapping is specified, but simply identifies the mapping kind ("substreams/graph-entities") and the apiVersion. - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -The `subgraph.yaml` also references a schema file. The requirements for this file are unchanged, but the entities specified must be compatible with the entity changes produced by the Substreams module referenced in the `subgraph.yaml`. - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -Given the above, subgraph developers can use Graph CLI to deploy this Substreams-powered subgraph. - -> Substreams-powered subgraphs indexing mainnet Ethereum can be deployed to the [Subgraph Studio](https://thegraph.com/studio/). - -```bash -yarn install # install graph-cli -yarn subgraph:build # build the subgraph -yarn subgraph:deploy # deploy the subgraph -``` - -That's it! You have built and deployed a Substreams-powered subgraph. - -## Serving Substreams-powered subgraphs - -In order to serve Substreams-powered subgraphs, Graph Node must be configured with a Substreams provider for the relevant network, as well as a Firehose or RPC to track the chain head. These providers can be configured via a `config.toml` file: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/vi/substreams/developing/_meta.js b/website/pages/vi/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/vi/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/vi/substreams/developing/devcontainer.mdx b/website/pages/vi/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/vi/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/vi/substreams/developing/sinks/_meta.js b/website/pages/vi/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/vi/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/vi/substreams/developing/sinks/sinks.mdx b/website/pages/vi/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/vi/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/vi/substreams/developing/solana/_meta.js b/website/pages/vi/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/vi/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/vi/substreams/developing/solana/accountchanges.mdx b/website/pages/vi/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/vi/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/vi/substreams/developing/solana/solana.mdx b/website/pages/vi/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/vi/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/vi/substreams/developing/solana/transactions.mdx b/website/pages/vi/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/vi/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/vi/substreams/getting-started-substreams.mdx b/website/pages/vi/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/vi/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/vi/substreams/pubsubstreams.mdx b/website/pages/vi/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/vi/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/vi/substreams/sps/_meta.js b/website/pages/vi/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/vi/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/vi/substreams/sps/introduction.mdx b/website/pages/vi/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/vi/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/vi/substreams/sps/sps-faq.mdx b/website/pages/vi/substreams/sps/sps-faq.mdx deleted file mode 100644 index ec24f97300ae..000000000000 --- a/website/pages/vi/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Substreams-powered subgraphs FAQ ---- - -## What are Substreams? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. - -## What are Substreams-powered subgraphs? - -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs), which are compatible with subgraph entities. - -If you are already familiar with subgraph development, then note that Substreams-powered subgraphs can then be queried, just as if it had been produced by the AssemblyScript transformation layer, with all the Subgraph benefits, like providing a dynamic and flexible GraphQL API. - -## How are Substreams-powered subgraphs different from subgraphs? - -Subgraphs are made up of datasources which specify on-chain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen on-chain. - -By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular on-chain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. - -## What are the benefits of using Substreams-powered subgraphs? - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## What are the benefits of Substreams? - -There are many benefits to using Substreams, including: - -- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. - -- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). - -- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. - -- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. - -- Access to additional data which is not available as part of the JSON RPC - -- All the benefits of the Firehose. - -## What is the Firehose? - -Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. - -Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. - -## What are the benefits of the Firehose? - -There are many benefits to using Firehose, including: - -- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. - -- Prevents downtimes: Designed from the ground up for High Availability. - -- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. - -- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. - -- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. - -## Where can developers access more information about Substreams-powered subgraphs and Substreams? - -The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. - -The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## What is the role of Rust modules in Substreams? - -Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## What makes Substreams composable? - -When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. - -As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. - -## How can you build and deploy a Substreams-powered Subgraph? - -After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). - -## Where can I find examples of Substreams and Substreams-powered subgraphs? - -You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. - -## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? - -The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/vi/substreams/sps/triggers.mdx b/website/pages/vi/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/vi/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/vi/substreams/sps/tutorial.mdx b/website/pages/vi/substreams/sps/tutorial.mdx deleted file mode 100644 index 8912961e3be0..000000000000 --- a/website/pages/vi/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## Điều kiện tiên quyết - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/zh/sps/_meta.js b/website/pages/zh/sps/_meta.js new file mode 100644 index 000000000000..4ebd7d55a84f --- /dev/null +++ b/website/pages/zh/sps/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../en/sps/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/zh/sps/introduction.mdx b/website/pages/zh/sps/introduction.mdx new file mode 100644 index 000000000000..e26db72ad5d4 --- /dev/null +++ b/website/pages/zh/sps/introduction.mdx @@ -0,0 +1,29 @@ +--- +title: Introduction to Substreams-Powered Subgraphs +--- + +Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. + +## Overview + +Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. + +### Specifics + +There are two methods of enabling this technology: + +1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. + +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. + +You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. + +### Additional Resources + +Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: + +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) diff --git a/website/pages/zh/sps/sps-faq.mdx b/website/pages/zh/sps/sps-faq.mdx new file mode 100644 index 000000000000..8e553abfff21 --- /dev/null +++ b/website/pages/zh/sps/sps-faq.mdx @@ -0,0 +1,95 @@ +--- +title: Substreams-Powered Subgraphs FAQ +--- + +## What are Substreams? + +Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. It allows you to refine and shape blockchain data for fast and seamless digestion by end-user applications. + +Specifically, it's a blockchain-agnostic, parallelized, and streaming-first engine that serves as a blockchain data transformation layer. It's powered by [Firehose](https://firehose.streamingfast.io/), and enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](/substreams/developing/sinks/sinks/) their data anywhere. + +Substreams is developed by [StreamingFast](https://www.streamingfast.io/). Visit the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. + +## What are Substreams-powered subgraphs? + +[Substreams-powered subgraphs](/sps/introduction/) combine the power of Substreams with the queryability of subgraphs. When publishing a Substreams-powered Subgraph, the data produced by the Substreams transformations, can [output entity changes](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs) that are compatible with subgraph entities. + +If you are already familiar with subgraph development, note that Substreams-powered subgraphs can then be queried just as if it had been produced by the AssemblyScript transformation layer. This provides all the benefits of subgraphs, including a dynamic and flexible GraphQL API. + +## How are Substreams-powered subgraphs different from subgraphs? + +Subgraphs are made up of datasources which specify onchain events, and how those events should be transformed via handlers written in Assemblyscript. These events are processed sequentially, based on the order in which events happen onchain. + +By contrast, substreams-powered subgraphs have a single datasource which references a substreams package, which is processed by the Graph Node. Substreams have access to additional granular onchain data compared to conventional subgraphs, and can also benefit from massively parallelised processing, which can mean much faster processing times. + +## What are the benefits of using Substreams-powered subgraphs? + +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. + +## What are the benefits of Substreams? + +There are many benefits to using Substreams, including: + +- Composable: You can stack Substreams modules like LEGO blocks, and build upon community modules, further refining public data. + +- High-performance indexing: Orders of magnitude faster indexing through large-scale clusters of parallel operations (think BigQuery). + +- Sink anywhere: Sink your data to anywhere you want: PostgreSQL, MongoDB, Kafka, subgraphs, flat files, Google Sheets. + +- Programmable: Use code to customize extraction, do transformation-time aggregations, and model your output for multiple sinks. + +- Access to additional data which is not available as part of the JSON RPC + +- All the benefits of the Firehose. + +## What is the Firehose? + +Developed by [StreamingFast](https://www.streamingfast.io/), the Firehose is a blockchain data extraction layer designed from scratch to process the full history of blockchains at speeds that were previously unseen. Providing a files-based and streaming-first approach, it is a core component of StreamingFast's suite of open-source technologies and the foundation for Substreams. + +Go to the [documentation](https://firehose.streamingfast.io/) to learn more about the Firehose. + +## What are the benefits of the Firehose? + +There are many benefits to using Firehose, including: + +- Lowest latency & no polling: In a streaming-first fashion, the Firehose nodes are designed to race to push out the block data first. + +- Prevents downtimes: Designed from the ground up for High Availability. + +- Never miss a beat: The Firehose stream cursor is designed to handle forks and to continue where you left off in any condition. + +- Richest data model:  Best data model that includes the balance changes, the full call tree, internal transactions, logs, storage changes, gas costs, and more. + +- Leverages flat files: Blockchain data is extracted into flat files, the cheapest and most optimized computing resource available. + +## Where can developers access more information about Substreams-powered subgraphs and Substreams? + +The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. + +The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. + +The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. + +## What is the role of Rust modules in Substreams? + +Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. + +See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. + +## What makes Substreams composable? + +When using Substreams, the composition happens at the transformation layer enabling cached modules to be re-used. + +As an example, Alice can build a DEX price module, Bob can use it to build a volume aggregator for some tokens of his interest, and Lisa can combine four individual DEX price modules to create a price oracle. A single Substreams request will package all of these individual's modules, link them together, to offer a much more refined stream of data. That stream can then be used to populate a subgraph, and be queried by consumers. + +## How can you build and deploy a Substreams-powered Subgraph? + +After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). + +## Where can I find examples of Substreams and Substreams-powered subgraphs? + +You can visit [this Github repo](https://github.com/pinax-network/awesome-substreams) to find examples of Substreams and Substreams-powered subgraphs. + +## What do Substreams and Substreams-powered subgraphs mean for The Graph Network? + +The integration promises many benefits, including extremely high-performance indexing and greater composability by leveraging community modules and building on them. diff --git a/website/pages/zh/sps/triggers.mdx b/website/pages/zh/sps/triggers.mdx new file mode 100644 index 000000000000..137512f8baa7 --- /dev/null +++ b/website/pages/zh/sps/triggers.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Triggers +--- + +Use Custom Triggers and enable the full use GraphQL. + +## Overview + +Custom Triggers allow you to send data directly into your subgraph mappings file and entities, which are similar to tables and fields. This enables you to fully use the GraphQL layer. + +By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data in your subgraph's handler. This ensures efficient and streamlined data management within the subgraph framework. + +### Defining `handleTransactions` + +The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. + +```tsx +export function handleTransactions(bytes: Uint8Array): void { + let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).transactions // 1. + if (transactions.length == 0) { + log.info('No transactions found', []) + return + } + + for (let i = 0; i < transactions.length; i++) { + // 2. + let transaction = transactions[i] + + let entity = new Transaction(transaction.hash) // 3. + entity.from = transaction.from + entity.to = transaction.to + entity.save() + } +} +``` + +Here's what you're seeing in the `mappings.ts` file: + +1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object +2. Looping over the transactions +3. Create a new subgraph entity for every transaction + +To go through a detailed example of a trigger-based subgraph, [check out the tutorial](/sps/tutorial/). + +### Additional Resources + +To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). diff --git a/website/pages/zh/sps/tutorial.mdx b/website/pages/zh/sps/tutorial.mdx new file mode 100644 index 000000000000..dbdcf746fc1d --- /dev/null +++ b/website/pages/zh/sps/tutorial.mdx @@ -0,0 +1,153 @@ +--- +title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' +--- + +Successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. + +## Get Started + +For a video tutorial, check out [How to Index Solana with a Substreams-powered Subgraph](/sps/tutorial/#video-tutorial) + +### Prerequisites + +Before starting, make sure to: + +- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. +- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. + +### Step 1: Initialize Your Project + +1. Open your Dev Container and run the following command to initialize your project: + + ```bash + substreams init + ``` + +2. Select the "minimal" project option. +3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: + +```yaml +specVersion: v0.1.0 +package: + name: my_project_sol + version: v0.1.0 + +imports: # Pass your spkg of interest + solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg + +modules: + - name: map_spl_transfers + use: solana:map_block # Select corresponding modules available within your spkg + initialBlock: 260000082 + + - name: map_transactions_by_programid + use: solana:solana:transactions_by_programid_without_votes + +network: solana-mainnet-beta + +params: # Modify the param fields to meet your needs + # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE +``` + +### Step 2: Generate the Subgraph Manifest + +Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: + +```bash +substreams codegen subgraph +``` + +You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: + +```yaml +--- +dataSources: + - kind: substreams + name: my_project_sol + network: solana-mainnet-beta + source: + package: + moduleName: map_spl_transfers # Module defined in the substreams.yaml + file: ./my-project-sol-v0.1.0.spkg + mapping: + apiVersion: 0.0.7 + kind: substreams/graph-entities + file: ./src/mappings.ts + handler: handleTriggers +``` + +### Step 3: Define Entities in `schema.graphql` + +Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. + +Here is an example: + +```graphql +type MyTransfer @entity { + id: ID! + amount: String! + source: String! + designation: String! + signers: [String!]! +} +``` + +This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. + +### Step 4: Handle Substreams Data in `mappings.ts` + +With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. + +The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: + +```ts +import { Protobuf } from 'as-proto/assembly' +import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' +import { MyTransfer } from '../generated/schema' + +export function handleTriggers(bytes: Uint8Array): void { + const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) + + for (let i = 0; i < input.data.length; i++) { + const event = input.data[i] + + if (event.transfer != null) { + let entity_id: string = `${event.txnId}-${i}` + const entity = new MyTransfer(entity_id) + entity.amount = event.transfer!.instruction!.amount.toString() + entity.source = event.transfer!.accounts!.source + entity.designation = event.transfer!.accounts!.destination + + if (event.transfer!.accounts!.signer!.single != null) { + entity.signers = [event.transfer!.accounts!.signer!.single!.signer] + } else if (event.transfer!.accounts!.signer!.multisig != null) { + entity.signers = event.transfer!.accounts!.signer!.multisig!.signers + } + entity.save() + } + } +} +``` + +### Step 5: Generate Protobuf Files + +To generate Protobuf objects in AssemblyScript, run the following command: + +```bash +npm run protogen +``` + +This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. + +### Conclusion + +Congratulations! You've successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can take the next step by customizing your schema, mappings, and modules to fit your specific use case. + +### Video Tutorial + + + +### Additional Resources + +For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). diff --git a/website/pages/zh/subgraphs/cookbook/substreams-powered-subgraphs.mdx b/website/pages/zh/subgraphs/cookbook/substreams-powered-subgraphs.mdx deleted file mode 100644 index 35b5d34c9bb2..000000000000 --- a/website/pages/zh/subgraphs/cookbook/substreams-powered-subgraphs.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: 基于Substreams的子图 ---- - -[Substreams](/substreams/introduction/) is a new framework for processing blockchain data, developed by StreamingFast for The Graph Network. A substreams modules can output entity changes, which are compatible with Subgraph entities. A subgraph can use such a Substreams module as a data source, bringing the indexing speed and additional data of Substreams to subgraph developers. - -## 要求 - -This cookbook requires [yarn](https://yarnpkg.com/), [the dependencies necessary for local Substreams development](https://substreams.streamingfast.io/documentation/consume/installing-the-cli), and the latest version of Graph CLI (>=0.52.0): - -``` -npm install -g @graphprotocol/graph-cli -``` - -## 获取手册 - -> 本手册使用这个基于Substreams的子图[Substreams-powered subgraph as a reference](https://github.com/graphprotocol/graph-tooling/tree/main/examples/substreams-powered-subgraph)作为参考。 - -``` -graph init --from-example substreams-powered-subgraph -``` - -## 定义Substreams包 - -A Substreams package is composed of types (defined as [Protocol Buffers](https://protobuf.dev/)), modules (written in Rust), and a `substreams.yaml` file which references the types, and specifies how modules are triggered. [Visit the Substreams documentation to learn more about Substreams development](/substreams/introduction/), and check out [awesome-substreams](https://github.com/pinax-network/awesome-substreams) and the [Substreams cookbook](https://github.com/pinax-network/substreams-cookbook) for more examples. - -该Substreams包可以检测以太坊主网上的合约部署,并跟踪所有新部署合约的创建块和时间戳。为此,在/proto/example.proto中有一个专门的Contract类型(了解更多关于定义Protocol Buffers的信息[learn more about defining Protocol Buffers](https://protobuf.dev/programming-guides/proto3/#simple)): - -```proto -syntax = "proto3"; - -package example; - -message Contracts { - repeated Contract contracts = 1; -} - -message Contract { - string address = 1; - uint64 blockNumber = 2; - string timestamp = 3; - uint64 ordinal = 4; -} -``` - -Substreams包的核心逻辑是lib.rs中的map_contract模块,它处理每个区块,过滤未回滚的Create调用,并返回Contracts: - -```rust -#[substreams::handlers::map] -fn map_contract(block: eth::v2::Block) -> Result { - let contracts = block - .transactions() - .flat_map(|tx| { - tx.calls - .iter() - .filter(|call| !call.state_reverted) - .filter(|call| call.call_type == eth::v2::CallType::Create as i32) - .map(|call| Contract { - address: format!("0x{}", Hex(&call.address)), - block_number: block.number, - timestamp: block.timestamp_seconds().to_string(), - ordinal: tx.begin_ordinal, - }) - }) - .collect(); - Ok(Contracts { contracts }) -} -``` - -只要Substreams包有一个模块输出与子图兼容的实体变更,就可以被子图使用。示例Substreams包中还有一个额外的graph_out模块在lib.rs中,它返回一个substreams_entity_change::pb::entity::EntityChanges输出,Graph Node可以处理该输出。 - -> Substreams_entity_change crate还有一个专门的Tables函数,用于生成实体变更(文档[documentation](https://docs.rs/substreams-entity-change/1.2.2/substreams_entity_change/tables/index.html))。生成的实体变更必须与相应子图的subgraph.graphql中定义的schema.graphql实体兼容。 - -```rust -#[substreams::handlers::map] -pub fn graph_out(contracts: Contracts) -> Result { - // hash map of name to a table - let mut tables = Tables::new(); - - for contract in contracts.contracts.into_iter() { - tables - .create_row("Contract", contract.address) - .set("timestamp", contract.timestamp) - .set("blockNumber", contract.block_number); - } - - Ok(tables.to_entity_changes()) -} -``` - -这些类型和模块在substreams.yaml中汇集在一起: - -```yaml -specVersion: v0.1.0 -package: - name: 'substreams_test' # the name to be used in the .spkg - version: v1.0.1 # the version to use when creating the .spkg - -imports: # dependencies - entity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkg - -protobuf: # specifies custom types for use by Substreams modules - files: - - example.proto - importPaths: - - ./proto - -binaries: - default: - type: wasm/rust-v1 - file: ./target/wasm32-unknown-unknown/release/substreams.wasm - -modules: # specify modules with their inputs and outputs. - - name: map_contract - kind: map - inputs: - - source: sf.ethereum.type.v2.Block - output: - type: proto:test.Contracts - - - name: graph_out - kind: map - inputs: - - map: map_contract - output: - type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node -``` - -您可以通过运行substreams graph来检查从区块到map_contract到graph_out的整体"流程": - -```mermaid -graph TD; - map_contract[map: map_contract]; - sf.ethereum.type.v2.Block[source: sf.ethereum.type.v2.Block] --> map_contract; - graph_out[map: graph_out]; - map_contract --> graph_out; -``` - -为了准备这个Substreams包供子图使用,您必须运行以下命令: - -```bash -yarn substreams:protogen # 生成/src/pb中的类型 -yarn substreams:build # 构建Substreams -yarn substreams:package # 将Substreams打包成.spkg文件 - -# 或者,yarn substreams:prepare会调用上述所有命令 -``` - -> 这些脚本在package.json文件中定义,如果想了解底层的Substreams命令,可以查看这些脚本。 - -这将根据substreams.yaml中的包名称和版本生成一个spkg文件。spkg文件包含了Graph Node需要获取此Substreams包的所有信息。 - -> 如果您更新了Substreams包,根据所做的更改,您可能需要运行部分或全部上述命令,以使spkg保持更新。 - -## 定义一个基于Substreams的子图 - -Substreams-powered subgraphs引入了一种名为"substreams"的新型数据源。这样的子图只能包含一个数据源。 - -基于Substreams的子图引入了一种新的数据源类型,"substreams"。这样的子图只能有一个数据源。该数据源必须指定Substreams网络、Substreams包(spkg)的相对文件位置,以及该Substreams包中生成子图兼容实体变更的模块(在本例中为map_entity_changes)。映射是指定的,但只是标识了映射类型("substreams/graph-entities")和apiVersion。 - -> Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index `mainnet` (Mainnet Ethereum). - -```yaml -specVersion: 0.0.4 -description: Ethereum Contract Tracking Subgraph (powered by Substreams) -repository: https://github.com/graphprotocol/graph-tooling -schema: - file: schema.graphql -dataSources: - - kind: substreams - name: substream_test - network: mainnet - source: - package: - moduleName: graph_out - file: substreams-test-v1.0.1.spkg - mapping: - kind: substreams/graph-entities - apiVersion: 0.0.5 -``` - -Subgraph.yaml还引用了一个模式文件。对于这个文件的要求没有变化,但是指定的实体必须与subgraph.yaml中引用的Substreams模块生成的实体变更兼容。 - -```graphql -type Contract @entity { - id: ID! - - "The timestamp when the contract was deployed" - timestamp: String! - - "The block number of the contract deployment" - blockNumber: BigInt! -} -``` - -有了以上内容,子图开发者可以使用Graph CLI部署这个基于Substreams的子图。 - -> 基于Substreams的子图索引以太坊主网可以部署到[Subgraph Studio](https://thegraph.com/studio/)。 - -```bash -yarn install # 安装graph-cli -yarn subgraph:build # 构建子图 -yarn subgraph:deploy # 部署子图 -``` - -就是这样!您已经构建并部署了一个基于Substreams的子图。 - -## 服务基于Substreams的子图 - -为了服务基于Substreams的子图,Graph Node必须配置与相关网络的Substreams提供程序,以及用于跟踪链头的Firehose或RPC。这些提供程序可以通过config.toml文件进行配置: - -```toml -[chains.mainnet] -shard = "main" -protocol = "ethereum" -provider = [ - { label = "substreams-provider-mainnet", - details = { type = "substreams", - url = "https://mainnet-substreams-url.grpc.substreams.io/", - token = "exampletokenhere" }}, - { label = "firehose-provider-mainnet", - details = { type = "firehose", - url = "https://mainnet-firehose-url.grpc.firehose.io/", - token = "exampletokenhere" }}, -] -``` diff --git a/website/pages/zh/substreams/developing/_meta.js b/website/pages/zh/substreams/developing/_meta.js new file mode 100644 index 000000000000..c155cc0e43ba --- /dev/null +++ b/website/pages/zh/substreams/developing/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../en/substreams/developing/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/zh/substreams/developing/devcontainer.mdx b/website/pages/zh/substreams/developing/devcontainer.mdx new file mode 100644 index 000000000000..4cadae4a3ebe --- /dev/null +++ b/website/pages/zh/substreams/developing/devcontainer.mdx @@ -0,0 +1,47 @@ +--- +title: Substreams Dev Container +--- + +Develop your first project with Substreams Dev Container. + +## What is a Dev Container? + +It's a tool to help you build your first project. You can either run it remotely through Github codespaces or locally by cloning the [substreams starter repository](https://github.com/streamingfast/substreams-starter?tab=readme-ov-file). + +Inside the Dev Container, the `substreams init` command sets up a code-generated Substreams project, allowing you to easily build a subgraph or an SQL-based solution for data handling. + +## Prerequisites + +- Ensure Docker and VS Code are up-to-date. + +## Navigating the Dev Container + +In the Dev Container, you can either build or import your own `substreams.yaml` and associate modules within the minimal path or opt for the automatically generated Substreams paths. Then, when you run the `Substreams Build` it will generate the Protobuf files. + +### Options + +- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. + +To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: + +- `substreams registry login` +- `substreams registry publish` + +> Note: If you run into any problems within the Dev Container, use the `help` command to access trouble shooting tools. + +## Building a Sink for Your Project + +You can configure your project to query data either through a Subgraph or directly from an SQL database: + +- **Subgraph**: Run `substreams codegen subgraph`. This generates a project with a basic `schema.graphql` and `mappings.ts` file. You can customize these to define entities based on the data extracted by Substreams. For more configurations, see [subgraph sink documentation](https://docs.substreams.dev/how-to-guides/sinks/subgraph). +- **SQL**: Run `substreams codegen sql` for SQL-based queries. For more information on configuring a SQL sink, refer to the [SQL documentation](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). + +## Deployment Options + +To deploy a Subgraph, you can either run the `graph-node` locally using the `deploy-local` command or deploy to Subgraph Studio by using the `deploy` command found in the `package.json` file. + +## Common Errors + +- When running locally, make sure to verify that all Docker containers are healthy by running the `dev-status` command. +- If you put the wrong start-block while generating your project, navigate to the `substreams.yaml` to change the block number, then re-run `substreams build`. diff --git a/website/pages/zh/substreams/developing/sinks/_meta.js b/website/pages/zh/substreams/developing/sinks/_meta.js new file mode 100644 index 000000000000..cc5f7723cbe2 --- /dev/null +++ b/website/pages/zh/substreams/developing/sinks/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/sinks/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/zh/substreams/developing/sinks/sinks.mdx b/website/pages/zh/substreams/developing/sinks/sinks.mdx new file mode 100644 index 000000000000..0429bd56ce34 --- /dev/null +++ b/website/pages/zh/substreams/developing/sinks/sinks.mdx @@ -0,0 +1,51 @@ +--- +title: Official Sinks +--- + +Choose a sink that meets your project's needs. + +## Overview + +Once you find a package that fits your needs, you can choose how you want to consume the data. + +Sinks are integrations that allow you to send the extracted data to different destinations, such as a SQL database, a file or a subgraph. + +## Sinks + +> Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. + +- [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. +- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. +- [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. +- [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. + +> Important: If you’d like your sink (e.g., SQL or PubSub) hosted for you, reach out to the StreamingFast team [here](mailto:sales@streamingfast.io). + +## Navigating Sink Repos + +### Official + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| SQL | O | StreamingFast | [substreams-sink-sql](https://github.com/streamingfast/substreams-sink-sql) | +| Go SDK | O | StreamingFast | [substreams-sink](https://github.com/streamingfast/substreams-sink) | +| Rust SDK | O | StreamingFast | [substreams-sink-rust](https://github.com/streamingfast/substreams-sink-rust) | +| JS SDK | O | StreamingFast | [substreams-js](https://github.com/substreams-js/substreams-js) | +| KV Store | O | StreamingFast | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | O | Pinax | [substreams-sink-prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | +| Webhook | O | Pinax | [substreams-sink-webhook](https://github.com/pinax-network/substreams-sink-webhook) | +| CSV | O | Pinax | [substreams-sink-csv](https://github.com/pinax-network/substreams-sink-csv) | +| PubSub | O | StreamingFast | [substreams-sink-pubsub](https://github.com/streamingfast/substreams-sink-pubsub) | + +### Community + +| Name | Support | Maintainer | Source Code | +| --- | --- | --- | --- | +| MongoDB | C | Community | [substreams-sink-mongodb](https://github.com/streamingfast/substreams-sink-mongodb) | +| Files | C | Community | [substreams-sink-files](https://github.com/streamingfast/substreams-sink-files) | +| KV Store | C | Community | [substreams-sink-kv](https://github.com/streamingfast/substreams-sink-kv) | +| Prometheus | C | Community | [substreams-sink-Prometheus](https://github.com/pinax-network/substreams-sink-prometheus) | + +- O = Official Support (by one of the main Substreams providers) +- C = Community Support diff --git a/website/pages/zh/substreams/developing/solana/_meta.js b/website/pages/zh/substreams/developing/solana/_meta.js new file mode 100644 index 000000000000..65a6f4a3956c --- /dev/null +++ b/website/pages/zh/substreams/developing/solana/_meta.js @@ -0,0 +1,5 @@ +import meta from '../../../../en/substreams/developing/solana/_meta.js' + +export default { + ...meta, +} diff --git a/website/pages/zh/substreams/developing/solana/accountchanges.mdx b/website/pages/zh/substreams/developing/solana/accountchanges.mdx new file mode 100644 index 000000000000..505d27d28db4 --- /dev/null +++ b/website/pages/zh/substreams/developing/solana/accountchanges.mdx @@ -0,0 +1,62 @@ +--- +title: Solana Account Changes +--- + +Learn how to consume Solana account change data using Substreams. + +## Introduction + +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. + +By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. + +- History for the Solana Account Changes dates as of 2025, block 310629601. + +- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). + +## Getting Started + +### Prerequisites + +Before you begin, ensure that you have the following: + +1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. +2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). + +### Step 1: Set Up a Connection to Solana Account Change Substreams + +Now that you have Substreams CLI installed, you can set up a connection to the Solana Account Change Substreams feed. + +- Using the [Solana Accounts Foundational Module](https://substreams.dev/packages/solana-accounts-foundational/latest), you can choose to stream data directly or use the GUI for a more visual experience. The following `gui` example filters for Honey Token account data. + +```bash + substreams gui solana-accounts-foundational filtered_accounts -t +10 -p filtered_accounts="owner:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || account:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy" +``` + +- This command will stream account changes directly to your terminal. + +```bash +substreams run solana-accounts-foundational filtered_accounts -s -1 -o clock +``` + +The Foundational Module has support for filtering on specific accounts and/or owners. You can adjust the query based on your needs. + +### Step 2: Sink the Substreams + +Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). + +### Step 3: Setting up a Reconnection Policy + +[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. + +When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: + +```go +import ( + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" +) + +type BlockScopedDataHandler = func(ctx context.Context, cursor *Cursor, data *pbsubstreamsrpc.BlockScopedData) error +type BlockUndoSignalHandler = func(ctx context.Context, cursor *Cursor, undoSignal *pbsubstreamsrpc.BlockUndoSignal) error +``` diff --git a/website/pages/zh/substreams/developing/solana/solana.mdx b/website/pages/zh/substreams/developing/solana/solana.mdx new file mode 100644 index 000000000000..2b5e975a1f6f --- /dev/null +++ b/website/pages/zh/substreams/developing/solana/solana.mdx @@ -0,0 +1,15 @@ +--- +title: Solana +--- + +Enhance your Solana built with Substreams. + +## Overview + +With Substreams on Solana, you can: + +- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: + 1. History for the Solana Account Changes dates as of 2025, block 310629601. + 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. +- Experience low-latency streaming + - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. diff --git a/website/pages/zh/substreams/developing/solana/transactions.mdx b/website/pages/zh/substreams/developing/solana/transactions.mdx new file mode 100644 index 000000000000..4f406826a957 --- /dev/null +++ b/website/pages/zh/substreams/developing/solana/transactions.mdx @@ -0,0 +1,60 @@ +--- +title: Solana Transactions +--- + +Learn how to initialize a Solana-based Substreams project within the Dev Container. + +> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). + +## Options + +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). + +## Step 1: Initialize Your Solana Substreams Project + +1. Open the [Dev Container](https://github.com/streamingfast/substreams-starter) and follow the on-screen steps to initialize your project. + +2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: + - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. + - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + +The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. + +To access voting transactions, use the full Solana block, `sf.solana.type.v1.Block`, as input. + +## Step 2: Visualize the Data + +1. Run `substreams auth` to create your [account](https://thegraph.market/) and generate an authentication token (JWT), then pass this token back as input. + +2. Now you can freely use the `substreams gui` to visualize and iterate on your extracted data. + +## Step 2.5: (Optionally) Transform the Data + +Within the generated directories, modify your Substreams modules to include additional filters, aggregations, and transformations, then update the manifest accordingly. + +## Step 3: Load the Data + +To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. + +### Subgraph + +1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. +2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Deploy + +### SQL + +1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. +2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. + +> Note: Run `help` to better navigate the development environment and check the health of containers. + +## Additional Resources + +You may find these additional resources helpful for developing your first Solana application. + +- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. +- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. diff --git a/website/pages/zh/substreams/getting-started-substreams.mdx b/website/pages/zh/substreams/getting-started-substreams.mdx new file mode 100644 index 000000000000..4d06508f31eb --- /dev/null +++ b/website/pages/zh/substreams/getting-started-substreams.mdx @@ -0,0 +1,41 @@ +--- +title: Substreams Quick Start +--- + +Discover how to utilize ready-to-use substream packages or develop your own. + +## Overview + +Integrating Substreams can be quick and easy. They are permissionless, and you can [obtain a key here](https://thegraph.market/) without providing personal information to start streaming on-chain data. + +## Start Building + +### Use Substreams Packages + +There are many ready-to-use Substreams packages available. You can explore these packages by visiting the [Substreams Registry](https://substreams.dev) and [sinking them](/substreams/developing/sinks/sinks/). The registry lets you search for and find any package that meets your needs. + +Once you find a package that fits your needs, you can choose how you want to consume the data: + +- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. +- **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. +- **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. + +### Develop Your Own + +If you can't find a Substreams package that meets your specific needs, you can develop your own. Substreams are built with Rust, so you'll write functions that extract and filter the data you need from the blockchain. To get started, check out the following tutorials: + +- [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) +- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-solana) +- [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) +- [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) +- [MANTRA](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/mantra) + +To build and optimize your Substreams from zero, use the minimal path within the [Dev Container](/substreams/developing/devcontainer/). + +> Note: Substreams guarantees that you'll [never miss data](https://docs.substreams.dev/reference-material/reliability-guarantees) with a simple reconnection policy. + +## Additional Resources + +- For additional guidance, reference the [Tutorials](https://docs.substreams.dev/tutorials/intro-to-tutorials) and follow the [How-To Guides](https://docs.substreams.dev/how-to-guides/develop-your-own-substreams) on Streaming Fast docs. +- For a deeper understanding of how Substreams works, explore the [architectural overview](https://docs.substreams.dev/reference-material/architecture) of the data service. diff --git a/website/pages/zh/substreams/pubsubstreams.mdx b/website/pages/zh/substreams/pubsubstreams.mdx new file mode 100644 index 000000000000..3c02d60f9ffd --- /dev/null +++ b/website/pages/zh/substreams/pubsubstreams.mdx @@ -0,0 +1,52 @@ +--- +title: Publishing a Substreams Package +--- + +Learn how to publish a Substreams package to the [Substreams Registry](https://substreams.dev). + +## Overview + +### What is a package? + +A Substreams package is a precompiled binary file that defines the specific data you want to extract from the blockchain, similar to the `mapping.ts` file in traditional subgraphs. + +## Publish a Package + +### Prerequisites + +- You must have the Substreams CLI installed. +- You must have a Substreams package (`.spkg`) that you want to publish. + +### Step 1: Run the `substreams publish` Command + +1. In a command-line terminal, run `substreams publish .spkg`. + +2. If you do not have a token set in your computer, navigate to `https://substreams.dev/me`. + +![get token](/img/1_get-token.png) + +### Step 2: Get a Token in the Substreams Registry + +1. In the Substreams Registry, log in with your GitHub account. + +2. Create a new token and copy it in a safe location. + +![new token](/img/2_new_token.png) + +### Step 3: Authenticate in the Substreams CLI + +1. Back in the Substreams CLI, paste the previously generated token. + +![paste token](/img/3_paste_token.png) + +2. Lastly, confirm that you want to publish the package. + +![confirm](/img/4_confirm.png) + +That's it! You have succesfully published a package in the Substreams registry. + +![success](/img/5_success.png) + +## Additional Resources + +Visit [Substreams](https://substreams.dev/) to explore a growing collection of ready-to-use Substreams packages across various blockchain networks. diff --git a/website/pages/zh/substreams/sps/_meta.js b/website/pages/zh/substreams/sps/_meta.js deleted file mode 100644 index 4d3f3456c0c4..000000000000 --- a/website/pages/zh/substreams/sps/_meta.js +++ /dev/null @@ -1,5 +0,0 @@ -import meta from '../../../en/sps/_meta.js' - -export default { - ...meta, -} diff --git a/website/pages/zh/substreams/sps/introduction.mdx b/website/pages/zh/substreams/sps/introduction.mdx deleted file mode 100644 index fd16c10f5c19..000000000000 --- a/website/pages/zh/substreams/sps/introduction.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Introduction to Substreams-powered Subgraphs ---- - -By using a Substreams package (`.spkg`) as a data source, your subgraph gains access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. - -There are two methods of enabling this technology: - -Using Substreams [triggers](/substreams/sps/triggers/): Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. - -Using [Entity Changes](https://substreams.streamingfast.io/documentation/consume/subgraph/graph-out): By writing more of the logic into Substreams, you can consume the module's output directly into graph-node. In graph-node, you can use the Substreams data to create your subgraph entities. - -It is really a matter of where you put your logic, in the subgraph or the Substreams. Keep in mind that having more of your logic in Substreams benefits from a parallelized model, whereas triggers will be linearly consumed in graph-node. - -Visit the following links for How-To Guides on using code-generation tooling to build your first end-to-end project quickly: - -- [Solana](https://substreams.streamingfast.io/documentation/how-to-guides/solana) -- [EVM](https://substreams.streamingfast.io/documentation/how-to-guides/evm) -- [Injective](https://substreams.streamingfast.io/documentation/how-to-guides/injective) diff --git a/website/pages/zh/substreams/sps/sps-faq.mdx b/website/pages/zh/substreams/sps/sps-faq.mdx deleted file mode 100644 index 69c3d0631722..000000000000 --- a/website/pages/zh/substreams/sps/sps-faq.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: 基于Substreams的子图 ---- - -## 什么是Substreams? - -Developed by [StreamingFast](https://www.streamingfast.io/), Substreams is an exceptionally powerful processing engine capable of consuming rich streams of blockchain data. Substreams allow you to refine and shape blockchain data for fast and seamless digestion by end-user applications. More specifically, Substreams is a blockchain-agnostic, parallelized, and streaming-first engine, serving as a blockchain data transformation layer. Powered by the [Firehose](https://firehose.streamingfast.io/), it ​​enables developers to write Rust modules, build upon community modules, provide extremely high-performance indexing, and [sink](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) their data anywhere. - -Go to the [Substreams Documentation](/substreams/introduction/) to learn more about Substreams. - -## 什么是基于Substreams的子图? - -[Substreams-powered subgraphs](/subgraphs/cookbook/substreams-powered-subgraphs/)将Substreams的强大功能与子图(subgraphs)的可查询性相结合。在发布一个由Substreams驱动的子图时,Substreams的转换过程产生的数据可以[输出实体变更](https://github.com/streamingfast/substreams-sink-entity-changes/blob/develop/substreams-entity-change/src/tables.rs),这些实体变更与子图的实体是兼容的。 - -如果您已经熟悉子图(Subgraph)开发,那么请注意,基于Substreams的子图可以被查询,就像它是由AssemblyScript转换层生成的一样,具有所有子图的优势,比如提供动态和灵活的GraphQL API。 - -## 基于Substreams的子图和普通子图有什么区别? - -子图由数据源组成,这些数据源指定了在链上发生的事件以及通过用Assemblyscript编写的处理程序应如何转换这些事件。这些事件按照链上发生事件的顺序依次进行处理。 - -相比之下,由Substreams支持的子图具有单一数据源,该数据源引用一个Substreams包,由图节点进行处理。与传统的子图相比,Substreams可以访问更多精细的链上数据,并且还可以从大规模并行处理中获益,这可能意味着处理时间更快。 - -## 使用基于Substeams的子图的优势是什么? - -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. - -## Substreams的优势是什么? - -使用Substreams有许多好处,包括: - -- 可组合的: Substreams模块具有可组合性,就像乐高积木一样,您可以将它们堆叠起来,并在社区模块的基础上构建,进一步细化公共数据。 - -- 高性能索引:大规模并行操作(类似于BigQuery)能够使索引速度提升数个数量级。 - -- 任意传输:将您的数据传输到您想要的任何地方:PostgreSQL、MongoDB、Kafka、子图、平面文件、Google Sheets等。 - -- 可编程:使用代码自定义提取、进行转换时聚合,并为多个传输目标建模输出。 - -- 访问不作为JSON RPC的一部分的附加数据。 - -- Firehose的全部好处。 - -## 什么是Firehose? - -Firehose是由[StreamingFast](https://www.streamingfast.io/)开发的区块链数据提取层,从零开始设计,以前所未有的速度处理区块链的完整历史。它提供基于文件和流式优先的方法,是StreamingFast开源技术套件的核心组件,也是Substreams的基础。 - -请访问[documentation](https://firehose.streamingfast.io/),了解更多关于Firehose的信息。 - -## Firehose的优势是什么? - -使用Firehose有许多好处,包括: - -- 最低延迟和无需轮询:Firehose节点以流优先的方式设计,竞相将块数据推送出去。 - -- 防止宕机:从头开始为高可用性而设计。 - -- 不会错过任何数据:Firehose流游标设计用于处理分叉,并在任何情况下都可以继续从上次离开的地方开始。 - -- 最丰富的数据模型:包含余额变化、完整的调用树、内部交易、日志、存储变更、燃气费用等最佳数据模型。 - -- 利用平面文件:将区块链数据提取到平面文件中,这是目前最便宜、最优化的计算资源。 - -## 开发人员在哪里可以获得关于Substreams-powered子图和Substreams的更多信息? - -The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. - -[Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) 将向您展示如何将它们打包部署在The Graph上。 - -The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. - -## Rust模块在Substreams中扮演什么角色? - -Rust模块相当于子图中的AssemblyScript mappers。它们以类似的方式编译为WASM,但编程模型允许并行执行。它们定义了您想要对原始区块链数据应用的转换和聚合类型。 - -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. - -## 什么使Substreams具有组合性? - -在使用Substreams时,组合发生在转换层,从而使得缓存模块可以被重复使用。 - -举例来说,Alice可以构建一个DEX价格模块,Bob可以使用它来构建一种感兴趣的代币的交易量聚合器,Lisa可以将四个单独的DEX价格模块组合起来创建一个价格预言机。一个单独的Substreams请求将打包所有这些个人模块,并将它们链接在一起,提供一个更加精细的数据流。然后可以使用该数据流填充子图,并由消费者查询。 - -## 如何构建和部署Substreams-powered子图? - -在[defining](/subgraphs/cookbook/substreams-powered-subgraphs/)Substreams-powered子图之后,您可以使用Graph CLI在[Subgraph Studio](https://thegraph.com/studio/)上部署它。 - -## 在哪里可以找到Substreams和Substreams-powered子图的示例? - -您可以访问此 [this Github repo](https://github.com/pinax-network/awesome-substreams) 以找到Substreams和Substreams-powered子图的示例。 - -## Substreams和Substreams-powered子图对于The Graph Network意味着什么? - -这种集成带来许多好处,包括通过利用社区模块和在其上构建的组合性来实现极高性能的索引。 diff --git a/website/pages/zh/substreams/sps/triggers.mdx b/website/pages/zh/substreams/sps/triggers.mdx deleted file mode 100644 index e5e510a6a7ad..000000000000 --- a/website/pages/zh/substreams/sps/triggers.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Substreams Triggers ---- - -Custom triggers allow you to send data directly into your subgraph mappings file and entities (similar to tables and fields), enabling full use of the GraphQL layer. By importing the Protobuf definitions emitted by your Substreams module, you can receive and process this data within your subgraph’s handler, ensuring efficient and streamlined data management within the subgraph framework. - -> Note: If you haven’t already, visit one of the How-To Guides found [here](/substreams/sps/introduction/) to scaffold your first project in the Development Container. - -The following code demonstrates how to define a `handleTransactions` function in a subgraph handler. This function receives raw Substreams bytes as a parameter and decodes them into a `Transactions` object. For each transaction, a new subgraph entity is created. - -```tsx -export function handleTransactions(bytes: Uint8Array): void { - let transactions = assembly.eth.transaction.v1.Transactions.decode(bytes.buffer).trasanctions // 1. - if (transactions.length == 0) { - log.info('No transactions found', []) - return - } - - for (let i = 0; i < transactions.length; i++) { - // 2. - let transaction = transactions[i] - - let entity = new Transaction(transaction.hash) // 3. - entity.from = transaction.from - entity.to = transaction.to - entity.save() - } -} -``` - -Here's what you’re seeing in the `mappings.ts` file: - -1. The bytes containing Substreams data are decoded into the generated `Transactions` object, this object is used like any other AssemblyScript object -2. Looping over the transactions -3. Create a new subgraph entity for every transaction - -To go through a detailed example of a trigger-based subgraph, [click here](/substreams/sps/tutorial/). diff --git a/website/pages/zh/substreams/sps/tutorial.mdx b/website/pages/zh/substreams/sps/tutorial.mdx deleted file mode 100644 index 9782a9989ba5..000000000000 --- a/website/pages/zh/substreams/sps/tutorial.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Tutorial: Set Up a Substreams-Powered Subgraph on Solana' ---- - -## 先决条件 - -Before starting, make sure to: - -- Complete the [Getting Started Guide](https://github.com/streamingfast/substreams-starter) to set up your development environment using a Dev Container. -- Be familiar with The Graph and basic blockchain concepts such as transactions and Protobufs. - -## Step 1: Initialize Your Project - - - -1. Open your Dev Container and run the following command to initialize your project: - - ```bash - substreams init - ``` - -2. Select the "minimal" project option. - -3. Replace the contents of the generated `substreams.yaml` file with the following configuration, which filters transactions for the Orca account on the SPL token program ID: - -```yaml -specVersion: v0.1.0 -package: - name: my_project_sol - version: v0.1.0 - -imports: # Pass your spkg of interest - solana: https://github.com/streamingfast/substreams-solana-spl-token/raw/master/tokens/solana-spl-token-v0.1.0.spkg - -modules: - - name: map_spl_transfers - use: solana:map_block # Select corresponding modules available within your spkg - initialBlock: 260000082 - - - name: map_transactions_by_programid - use: solana:solana:transactions_by_programid_without_votes - -network: solana-mainnet-beta - -params: # Modify the param fields to meet your needs - # For program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - map_spl_transfers: token_contract:orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE -``` - -## Step 2: Generate the Subgraph Manifest - -Once the project is initialized, generate a subgraph manifest by running the following command in the Dev Container: - -```bash -substreams codegen subgraph -``` - -You will generate a`subgraph.yaml` manifest which imports the Substreams package as a data source: - -```yaml ---- -dataSources: - - kind: substreams - name: my_project_sol - network: solana-mainnet-beta - source: - package: - moduleName: map_spl_transfers # Module defined in the substreams.yaml - file: ./my-project-sol-v0.1.0.spkg - mapping: - apiVersion: 0.0.7 - kind: substreams/graph-entities - file: ./src/mappings.ts - handler: handleTriggers -``` - -## Step 3: Define Entities in `schema.graphql` - -Define the fields you want to save in your subgraph entities by updating the `schema.graphql` file. Here is an example: - -```graphql -type MyTransfer @entity { - id: ID! - amount: String! - source: String! - designation: String! - signers: [String!]! -} -``` - -This schema defines a `MyTransfer` entity with fields such as `id`, `amount`, `source`, `designation`, and `signers`. - -## Step 4: Handle Substreams Data in `mappings.ts` - -With the Protobuf objects generated, you can now handle the decoded Substreams data in your `mappings.ts` file found in the `./src` directory. The example below demonstrates how to extract to subgraph entities the non-derived transfers associated to the Orca account id: - -```ts -import { Protobuf } from 'as-proto/assembly' -import { Events as protoEvents } from './pb/sf/solana/spl/token/v1/Events' -import { MyTransfer } from '../generated/schema' - -export function handleTriggers(bytes: Uint8Array): void { - const input: protoEvents = Protobuf.decode(bytes, protoEvents.decode) - - for (let i = 0; i < input.data.length; i++) { - const event = input.data[i] - - if (event.transfer != null) { - let entity_id: string = `${event.txnId}-${i}` - const entity = new MyTransfer(entity_id) - entity.amount = event.transfer!.instruction!.amount.toString() - entity.source = event.transfer!.accounts!.source - entity.designation = event.transfer!.accounts!.destination - - if (event.transfer!.accounts!.signer!.single != null) { - entity.signers = [event.transfer!.accounts!.signer!.single!.signer] - } else if (event.transfer!.accounts!.signer!.multisig != null) { - entity.signers = event.transfer!.accounts!.signer!.multisig!.signers - } - entity.save() - } - } -} -``` - -## Step 5: Generate Protobuf Files - -To generate Protobuf objects in AssemblyScript, run the following command: - -```bash -npm run protogen -``` - -This command converts the Protobuf definitions into AssemblyScript, allowing you to use them in the subgraph's handler. - -## Conclusion - -You’ve successfully set up a trigger-based Substreams-powered subgraph for a Solana SPL token. You can now further customize your schema, mappings, and modules to suit your specific use case. - -For more advanced customization and optimizations, check out the official [Substreams documentation](https://substreams.streamingfast.io/tutorials/solana). From 4960df78a1e0365a1a57847fc4b7a2983a317f85 Mon Sep 17 00:00:00 2001 From: giu Date: Fri, 24 Jan 2025 01:41:13 -0500 Subject: [PATCH 09/20] removing one solana doc --- .../en/substreams/developing/solana/_meta.js | 1 - .../developing/solana/accountchanges.mdx | 8 ++++---- .../en/substreams/developing/solana/solana.mdx | 15 --------------- 3 files changed, 4 insertions(+), 20 deletions(-) delete mode 100644 website/pages/en/substreams/developing/solana/solana.mdx diff --git a/website/pages/en/substreams/developing/solana/_meta.js b/website/pages/en/substreams/developing/solana/_meta.js index 8fa01df2bab6..de30a3f27299 100644 --- a/website/pages/en/substreams/developing/solana/_meta.js +++ b/website/pages/en/substreams/developing/solana/_meta.js @@ -1,5 +1,4 @@ export default { - solana: 'Solana Offerings', transactions: 'Transactions and Instructions', accountchanges: 'Account Changes', } diff --git a/website/pages/en/substreams/developing/solana/accountchanges.mdx b/website/pages/en/substreams/developing/solana/accountchanges.mdx index 505d27d28db4..d5fee78c8548 100644 --- a/website/pages/en/substreams/developing/solana/accountchanges.mdx +++ b/website/pages/en/substreams/developing/solana/accountchanges.mdx @@ -6,13 +6,13 @@ Learn how to consume Solana account change data using Substreams. ## Introduction -This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. +This guide walks you through the process of setting up your environment, configuring your first Substreams stream, and consuming account changes efficiently. By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. -By the end of this guide, you will have a working Substreams feed that allows you to track real-time account changes on the Solana blockchain, as well as historical account change data. +> NOTE: History for the Solana Account Changes dates as of 2025, block 310629601. -- History for the Solana Account Changes dates as of 2025, block 310629601. +For each Substreams Solana account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). -- For each Solana Account block, only the latest update per account is recorded, see the [Protobuf Referece](https://buf.build/streamingfast/firehose-solana/file/main:sf/solana/type/v1/account.proto). If an account is deleted, a payload with `deleted == True` is provided. Additionally, events of low importance ware omitted, such as those with the special owner “Vote11111111…” account or changes that do not affect the account data (ex: lamport changes). +> NOTE: To test Substreams latency for Solana accounts, measured as block-head drift, install the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. ## Getting Started diff --git a/website/pages/en/substreams/developing/solana/solana.mdx b/website/pages/en/substreams/developing/solana/solana.mdx deleted file mode 100644 index 2b5e975a1f6f..000000000000 --- a/website/pages/en/substreams/developing/solana/solana.mdx +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Solana ---- - -Enhance your Solana built with Substreams. - -## Overview - -With Substreams on Solana, you can: - -- Quickly index [Transaction and Instruction](./transactions.mdx) data and [Account Changes](./accountchanges.mdx). The Solana Account Changes endpoint offers both real-time and historical data, similar to other [supported endpoints](https://docs.substreams.dev/reference-material/chains-and-endpoints), with a few key differences: - 1. History for the Solana Account Changes dates as of 2025, block 310629601. - 2. The pricing model of Account Changes is based on Egress rather than Bytes Processed given the file sizes. -- Experience low-latency streaming - - You can test Substreams latency on Solana, which is measured as block-head drift, for yourself by installing the [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) and running `substreams run solana-common blocks_without_votes -s -1 -o clock`. From 16fc8015240a0565d627d49f12e2b19da1654359 Mon Sep 17 00:00:00 2001 From: Idalith <126833353+idalithb@users.noreply.github.com> Date: Fri, 24 Jan 2025 11:49:36 -0800 Subject: [PATCH 10/20] Update website/pages/en/_meta.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Benoît Rouleau --- website/pages/en/_meta.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/en/_meta.js b/website/pages/en/_meta.js index a2ec755c2c7c..33ff7aa81650 100644 --- a/website/pages/en/_meta.js +++ b/website/pages/en/_meta.js @@ -18,7 +18,7 @@ export default { }, '###2': { type: 'heading', - title: 'Substreams powered Subgraphs', + title: 'Substreams-Powered Subgraphs', }, sps: { type: 'children', From 6d784ff14d1b3aa60835d0f4e65b518a6893535e Mon Sep 17 00:00:00 2001 From: giu Date: Fri, 24 Jan 2025 19:06:51 -0500 Subject: [PATCH 11/20] fixes --- .../en/substreams/developing/sinks/sinks.mdx | 2 +- .../developing/solana/accountchanges.mdx | 10 +++++----- .../developing/solana/transactions.mdx | 18 +++++++++--------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/website/pages/en/substreams/developing/sinks/sinks.mdx b/website/pages/en/substreams/developing/sinks/sinks.mdx index 0429bd56ce34..c1080a92d6ca 100644 --- a/website/pages/en/substreams/developing/sinks/sinks.mdx +++ b/website/pages/en/substreams/developing/sinks/sinks.mdx @@ -15,7 +15,7 @@ Sinks are integrations that allow you to send the extracted data to different de > Note: Some of the sinks are officially supported by the StreamingFast core development team (i.e. active support is provided), but other sinks are community-driven and support can't be guaranteed. - [SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink): Send the data to a database. -- [Subgraph](./sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. +- [Subgraph](../../../sps/introduction.mdx): Configure an API to meet your data needs and host it on The Graph Network. - [Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream): Stream data directly from your application. - [PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub): Send data to a PubSub topic. - [Community Sinks](https://docs.substreams.dev/how-to-guides/sinks/community-sinks): Explore quality community maintained sinks. diff --git a/website/pages/en/substreams/developing/solana/accountchanges.mdx b/website/pages/en/substreams/developing/solana/accountchanges.mdx index d5fee78c8548..53ab95612a29 100644 --- a/website/pages/en/substreams/developing/solana/accountchanges.mdx +++ b/website/pages/en/substreams/developing/solana/accountchanges.mdx @@ -20,9 +20,9 @@ For each Substreams Solana account block, only the latest update per account is Before you begin, ensure that you have the following: -1. [Substreams CLI](../../references/cli/installing-the-cli.md) installed. -2. A [Substreams key](../../references/cli/authentication.md) for access to the Solana Account Change data. -3. Basic knowledge of [how to use](../../references/cli/command-line-interface.md) the command line interface (CLI). +1. [Substreams CLI](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli) installed. +2. A [Substreams key](https://docs.substreams.dev/reference-material/substreams-cli/authentication) for access to the Solana Account Change data. +3. Basic knowledge of [how to use](https://docs.substreams.dev/reference-material/substreams-cli/command-line-interface) the command line interface (CLI). ### Step 1: Set Up a Connection to Solana Account Change Substreams @@ -44,11 +44,11 @@ The Foundational Module has support for filtering on specific accounts and/or ow ### Step 2: Sink the Substreams -Consume the account stream [directly in your application](../../how-to-guides/sinks/stream/stream.md) using a callback or make it queryable by using the [SQL-DB sink](../../how-to-guides/sinks/sql/sql-sink.md). +Consume the account stream [directly in your application](https://docs.substreams.dev/how-to-guides/sinks/stream) using a callback or make it queryable by using the [SQL-DB sink](https://docs.substreams.dev/how-to-guides/sinks/sql-sink). ### Step 3: Setting up a Reconnection Policy -[Cursor Management](../../references/reliability-guarantees.md) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. +[Cursor Management](https://docs.substreams.dev/reference-material/reliability-guarantees) ensures seamless continuity and retraceability by allowing you to resume from the last consumed block if the connection is interrupted. This functionality prevents data loss and maintains a persistent stream. When creating or using a sink, the user's primary responsibility is to provide implementations of BlockScopedDataHandler and a BlockUndoSignalHandler implementation(s) which has the following interface: diff --git a/website/pages/en/substreams/developing/solana/transactions.mdx b/website/pages/en/substreams/developing/solana/transactions.mdx index 4f406826a957..86bb67082b49 100644 --- a/website/pages/en/substreams/developing/solana/transactions.mdx +++ b/website/pages/en/substreams/developing/solana/transactions.mdx @@ -8,7 +8,7 @@ Learn how to initialize a Solana-based Substreams project within the Dev Contain ## Options -If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](../references/cli/installing-the-cli.md). +If you prefer to begin locally within your terminal rather than through the Dev Container (VS Code required), refer to the [Substreams CLI installation guide](https://docs.substreams.dev/reference-material/substreams-cli/installing-the-cli). ## Step 1: Initialize Your Solana Substreams Project @@ -17,7 +17,7 @@ If you prefer to begin locally within your terminal rather than through the Dev 2. Running `substreams init` will give you the option to choose between two Solana project options. Select the best option for your project: - **sol-minimal**: This creates a simple Substreams that extracts raw Solana block data and generates corresponding Rust code. This path will start you with the full raw block, and you can navigate to the `substreams.yaml` (the manifest) to modify the input. - **sol-transactions**: This creates a Substreams that filters Solana transactions based on one or more Program IDs and/or Account IDs, using the cached [Solana Foundational Module](https://substreams.dev/streamingfast/solana-common/v0.3.0). - - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available, after using the `idl` subcommand within the [Anchor CLI](https://www.anchor-lang.com/docs/cli), then you’ll need to provide it yourself. + - **sol-anchor-beta**: This creates a Substreams that decodes instructions and events with an Anchor IDL. If an IDL isn’t available (reference [Anchor CLI](https://www.anchor-lang.com/docs/cli)), then you’ll need to provide it yourself. The modules within Solana Common do not include voting transactions. To gain a 75% reduction in data processing size and costs, delay your stream by over 1000 blocks from the head. This can be done using the [`sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) function in Rust. @@ -35,18 +35,18 @@ Within the generated directories, modify your Substreams modules to include addi ## Step 3: Load the Data -To make your Substreams queryable (as opposed to [direct streaming](../how-to-guides/sinks/stream/stream.md)), you can automatically generate a [Substreams-powered subgraph](/substreams/developing/sinks/sps/introduction/) or SQL-DB sink. +To make your Substreams queryable (as opposed to [direct streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)), you can automatically generate a [Substreams-powered subgraph](../../../sps/introduction.mdx) or SQL-DB sink. ### Subgraph 1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. -2. Create your [subgraph mappings](/how-to-guides/sinks/subgraph/triggers.md) within the `mappings.ts` and associated entities within the `schema.graphql`. -3. Deploy +2. Create your [subgraph mappings](../../../sps/triggers.mdx) within the `mappings.ts` and associated entities within the `schema.graphql`. +3. Build and deploy locally or to Studio by running `deploy-studio`. ### SQL 1. Run `substreams codegen sql` and choose from either ClickHouse or Postgres to initialize the sink, producing the necessary files. -2. Run `substreams build` build the [Substream SQL](/how-to-guides/sinks/sql/sql-sink.md) sink. +2. Run `substreams build` build the [Substream SQL](https://docs.substreams.dev/how-to-guides/sinks/sql-sink) sink. 3. Run `substreams-sink-sql` to sink the data into your selected SQL DB. > Note: Run `help` to better navigate the development environment and check the health of containers. @@ -55,6 +55,6 @@ To make your Substreams queryable (as opposed to [direct streaming](../how-to-gu You may find these additional resources helpful for developing your first Solana application. -- The [Dev Container Reference](/references/devcontainer-ref.md) helps you navigate the container and its common errors. -- The [CLI reference](/references/cli/command-line-interface.md) lets you explore all the tools available in the Substreams CLI. -- The [Components Reference](/references/substreams-components/packages.md) dives deeper into navigating the `substreams.yaml`. +- The [Dev Container Reference](../devcontainer.mdx) helps you navigate the container and its common errors. +- The [CLI reference](https://docs.substreams.dev/reference-material/substreams-cli/command-line-interface) lets you explore all the tools available in the Substreams CLI. +- The [Components Reference](https://docs.substreams.dev/reference-material/substreams-components/packages) dives deeper into navigating the `substreams.yaml`. From 3d989640fe8891e12e4775185f3e5172711fb7a8 Mon Sep 17 00:00:00 2001 From: Idalith Bustos Date: Fri, 24 Jan 2025 17:33:11 -0800 Subject: [PATCH 12/20] Updating sps links --- website/pages/en/sps/introduction.mdx | 6 +++--- website/pages/en/sps/sps-faq.mdx | 8 ++++---- website/pages/en/sps/triggers.mdx | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/website/pages/en/sps/introduction.mdx b/website/pages/en/sps/introduction.mdx index e26db72ad5d4..aa44f605ce65 100644 --- a/website/pages/en/sps/introduction.mdx +++ b/website/pages/en/sps/introduction.mdx @@ -12,9 +12,9 @@ Use a Substreams package (`.spkg`) as a data source, to give your subgraph acces There are two methods of enabling this technology: -1. **Using Substreams [triggers](/substreams/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. +1. **Using Substreams [triggers](/sps/triggers/)**: Consume from any Substreams module by importing the Protobuf model through a subgraph handler and move all your logic into a subgraph. This method creates the subgraph entities directly in the subgraph. -2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](docs/en/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. +2. **Using [Entity Changes](https://docs.substreams.dev/how-to-guides/sinks/subgraph/graph-out)**: By writing more of the logic into Substreams, you can consume the module's output directly into [graph-node](/indexing/tooling/graph-node/). In graph-node, you can use the Substreams data to create your subgraph entities. You can choose where to place your logic, either in the subgraph or Substreams. However, consider what aligns with your data needs, as Substreams has a parallelized model, and triggers are consumed linearly in the graph node. @@ -22,7 +22,7 @@ You can choose where to place your logic, either in the subgraph or Substreams. Visit the following links for tutorials on using code-generation tooling to build your first end-to-end Substreams project quickly: -- [Solana](https://docs.substreams.dev/tutorials/intro-to-tutorials/solana) +- [Solana](/substreams/developing/solana/transactions/) - [EVM](https://docs.substreams.dev/tutorials/intro-to-tutorials/evm) - [Starknet](https://docs.substreams.dev/tutorials/intro-to-tutorials/starknet) - [Injective](https://docs.substreams.dev/tutorials/intro-to-tutorials/on-cosmos/injective) diff --git a/website/pages/en/sps/sps-faq.mdx b/website/pages/en/sps/sps-faq.mdx index 8e553abfff21..dc99e916ed7a 100644 --- a/website/pages/en/sps/sps-faq.mdx +++ b/website/pages/en/sps/sps-faq.mdx @@ -24,7 +24,7 @@ By contrast, substreams-powered subgraphs have a single datasource which referen ## What are the benefits of using Substreams-powered subgraphs? -Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://substreams.streamingfast.io/documentation/develop/manifest-modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. +Substreams-powered subgraphs combine all the benefits of Substreams with the queryability of subgraphs. They bring greater composability and high-performance indexing to The Graph. They also enable new data use cases; for example, once you've built your Substreams-powered Subgraph, you can reuse your [Substreams modules](https://docs.substreams.dev/reference-material/substreams-components/modules#modules) to output to different [sinks](https://substreams.streamingfast.io/reference-and-specs/manifests#sink) such as PostgreSQL, MongoDB, and Kafka. ## What are the benefits of Substreams? @@ -66,7 +66,7 @@ There are many benefits to using Firehose, including: The [Substreams documentation](/substreams/introduction/) will teach you how to build Substreams modules. -The [Substreams-powered subgraphs documentation](/subgraphs/cookbook/substreams-powered-subgraphs/) will show you how to package them for deployment on The Graph. +The [Substreams-powered subgraphs documentation](/sps/introduction/) will show you how to package them for deployment on The Graph. The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substreams-codegen-no-code-tool-to-bootstrap-your-project-a11efe0378c6) will allow you to bootstrap a Substreams project without any code. @@ -74,7 +74,7 @@ The [latest Substreams Codegen tool](https://streamingfastio.medium.com/substrea Rust modules are the equivalent of the AssemblyScript mappers in subgraphs. They are compiled to WASM in a similar way, but the programming model allows for parallel execution. They define the sort of transformations and aggregations you want to apply to the raw blockchain data. -See [modules documentation](https://substreams.streamingfast.io/documentation/develop/manifest-modules) for details. +See [modules documentation](https://docs.substreams.dev/reference-material/substreams-components/modules#modules) for details. ## What makes Substreams composable? @@ -84,7 +84,7 @@ As an example, Alice can build a DEX price module, Bob can use it to build a vol ## How can you build and deploy a Substreams-powered Subgraph? -After [defining](/subgraphs/cookbook/substreams-powered-subgraphs/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). +After [defining](/sps/introduction/) a Substreams-powered Subgraph, you can use the Graph CLI to deploy it in [Subgraph Studio](https://thegraph.com/studio/). ## Where can I find examples of Substreams and Substreams-powered subgraphs? diff --git a/website/pages/en/sps/triggers.mdx b/website/pages/en/sps/triggers.mdx index 137512f8baa7..b346119555c1 100644 --- a/website/pages/en/sps/triggers.mdx +++ b/website/pages/en/sps/triggers.mdx @@ -44,4 +44,4 @@ To go through a detailed example of a trigger-based subgraph, [check out the tut ### Additional Resources -To scaffold your first project in the Development Container, check out one of the [How-To Guides](/sps/introduction/). +To scaffold your first project in the Development Container, check out one of the [How-To Guide](/substreams/developing/devcontainer/). From b6178a91e68a71373452f587478c9134e435d08a Mon Sep 17 00:00:00 2001 From: Idalith Bustos Date: Fri, 24 Jan 2025 17:51:39 -0800 Subject: [PATCH 13/20] Fixed links --- website/pages/en/substreams/developing/solana/transactions.mdx | 2 +- website/pages/en/substreams/getting-started-substreams.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/pages/en/substreams/developing/solana/transactions.mdx b/website/pages/en/substreams/developing/solana/transactions.mdx index 86bb67082b49..671e3c5dfd3c 100644 --- a/website/pages/en/substreams/developing/solana/transactions.mdx +++ b/website/pages/en/substreams/developing/solana/transactions.mdx @@ -4,7 +4,7 @@ title: Solana Transactions Learn how to initialize a Solana-based Substreams project within the Dev Container. -> Note: This guide excludes [Account Changes](substreams/developing/solana/accountchanges/). +> Note: This guide excludes [Account Changes](/substreams/developing/solana/accountchanges/). ## Options diff --git a/website/pages/en/substreams/getting-started-substreams.mdx b/website/pages/en/substreams/getting-started-substreams.mdx index 4d06508f31eb..5541cc56d347 100644 --- a/website/pages/en/substreams/getting-started-substreams.mdx +++ b/website/pages/en/substreams/getting-started-substreams.mdx @@ -16,7 +16,7 @@ There are many ready-to-use Substreams packages available. You can explore these Once you find a package that fits your needs, you can choose how you want to consume the data: -- **[Subgraph](/substreams/developing/sinks/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. +- **[Subgraph](/sps/introduction/)**: Configure an API to meet your data needs and host it on The Graph Network. - **[SQL Database](https://docs.substreams.dev/how-to-guides/sinks/sql-sink)**: Send the data to a database. - **[Direct Streaming](https://docs.substreams.dev/how-to-guides/sinks/stream)**: Stream data directly to your application. - **[PubSub](https://docs.substreams.dev/how-to-guides/sinks/pubsub)**: Send data to a PubSub topic. From 35cde32137404a87b5327487a69009efd82991e7 Mon Sep 17 00:00:00 2001 From: giu Date: Sun, 26 Jan 2025 17:25:06 -0500 Subject: [PATCH 14/20] fixed minimal explanation --- website/pages/en/substreams/developing/devcontainer.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/en/substreams/developing/devcontainer.mdx b/website/pages/en/substreams/developing/devcontainer.mdx index 4cadae4a3ebe..040c2f437566 100644 --- a/website/pages/en/substreams/developing/devcontainer.mdx +++ b/website/pages/en/substreams/developing/devcontainer.mdx @@ -20,7 +20,7 @@ In the Dev Container, you can either build or import your own `substreams.yaml` ### Options -- **Minimal**: Starts you with the raw block data. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Minimal**: Starts you with the raw block `.proto` and requires development. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. - **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: From 044634a6352e8c92327c920722a6df4b71dd9485 Mon Sep 17 00:00:00 2001 From: giu Date: Sun, 26 Jan 2025 17:38:29 -0500 Subject: [PATCH 15/20] fix --- website/pages/en/substreams/developing/devcontainer.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/en/substreams/developing/devcontainer.mdx b/website/pages/en/substreams/developing/devcontainer.mdx index 040c2f437566..cd65c8d046f8 100644 --- a/website/pages/en/substreams/developing/devcontainer.mdx +++ b/website/pages/en/substreams/developing/devcontainer.mdx @@ -20,7 +20,7 @@ In the Dev Container, you can either build or import your own `substreams.yaml` ### Options -- **Minimal**: Starts you with the raw block `.proto` and requires development. This path is intended for experienced users. You can navigate to the `substreams.yaml` to modify the input data source. +- **Minimal**: Starts you with the raw block `.proto` and requires development. This path is intended for experienced users. - **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: From ab38ef52362ee8140c5038582ad0ccd156b229cc Mon Sep 17 00:00:00 2001 From: giu Date: Sun, 26 Jan 2025 17:44:01 -0500 Subject: [PATCH 16/20] fix to add studio link --- website/pages/en/substreams/developing/solana/transactions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/en/substreams/developing/solana/transactions.mdx b/website/pages/en/substreams/developing/solana/transactions.mdx index 671e3c5dfd3c..8e5d7c35d4e7 100644 --- a/website/pages/en/substreams/developing/solana/transactions.mdx +++ b/website/pages/en/substreams/developing/solana/transactions.mdx @@ -41,7 +41,7 @@ To make your Substreams queryable (as opposed to [direct streaming](https://docs 1. Run `substreams codegen subgraph` to initialize the sink, producing the necessary files and function definitions. 2. Create your [subgraph mappings](../../../sps/triggers.mdx) within the `mappings.ts` and associated entities within the `schema.graphql`. -3. Build and deploy locally or to Studio by running `deploy-studio`. +3. Build and deploy locally or to [Subgraph Studio](https://thegraph.com/studio-pricing/) by running `deploy-studio`. ### SQL From 283c24a25440c540ecaa6c3ae72a975d439c2217 Mon Sep 17 00:00:00 2001 From: giu Date: Sun, 26 Jan 2025 18:57:58 -0500 Subject: [PATCH 17/20] clarifying the non-minimal path --- website/pages/en/substreams/developing/devcontainer.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/en/substreams/developing/devcontainer.mdx b/website/pages/en/substreams/developing/devcontainer.mdx index cd65c8d046f8..5b07c96c97ae 100644 --- a/website/pages/en/substreams/developing/devcontainer.mdx +++ b/website/pages/en/substreams/developing/devcontainer.mdx @@ -21,7 +21,7 @@ In the Dev Container, you can either build or import your own `substreams.yaml` ### Options - **Minimal**: Starts you with the raw block `.proto` and requires development. This path is intended for experienced users. -- **Non-Minimal**: Extracts filtered data using network-specific cache and Protobufs from the corresponding Foundational Modules that are built and maintained by the StreamingFast team. +- **Non-Minimal**: Extracts filtered data using network-specific caches and Protobufs taken from corresponding foundational modules (maintained by the StreamingFast team). This path generates a working Substreams out of the box. To share your work with the broader community, publish your `.spkg` to [Substreams registry](https://substreams.dev/) using: From a47d8e909d6329b5c27151375b5312335ebbbdcb Mon Sep 17 00:00:00 2001 From: Idalith Bustos Date: Mon, 27 Jan 2025 13:05:18 -0800 Subject: [PATCH 18/20] Updating left-nav --- website/pages/en/_meta.js | 8 ++++---- website/pages/en/sps/introduction.mdx | 2 +- website/pages/en/substreams/introduction.mdx | 2 +- website/src/_app.tsx | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/website/pages/en/_meta.js b/website/pages/en/_meta.js index 33ff7aa81650..f15304085f70 100644 --- a/website/pages/en/_meta.js +++ b/website/pages/en/_meta.js @@ -18,9 +18,9 @@ export default { }, '###2': { type: 'heading', - title: 'Substreams-Powered Subgraphs', + title: 'Substreams', }, - sps: { + substreams: { type: 'children', }, '---3': { @@ -28,9 +28,9 @@ export default { }, '###3': { type: 'heading', - title: 'Substreams', + title: 'Substreams-Powered Subgraphs', }, - substreams: { + sps: { type: 'children', }, '---4': { diff --git a/website/pages/en/sps/introduction.mdx b/website/pages/en/sps/introduction.mdx index aa44f605ce65..a084cf3cdd9c 100644 --- a/website/pages/en/sps/introduction.mdx +++ b/website/pages/en/sps/introduction.mdx @@ -6,7 +6,7 @@ Boost your subgraph’s efficiency and scalability by using [Substreams](/substr ## Overview -Use a Substreams package (`.spkg`) as a data source, to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. +Use a Substreams package (`.spkg`) as a data source to give your subgraph access to a stream of pre-indexed blockchain data. This enables more efficient and scalable data handling, especially with large or complex blockchain networks. ### Specifics diff --git a/website/pages/en/substreams/introduction.mdx b/website/pages/en/substreams/introduction.mdx index 25fcfa5a5c2c..95567b7ed53d 100644 --- a/website/pages/en/substreams/introduction.mdx +++ b/website/pages/en/substreams/introduction.mdx @@ -10,7 +10,7 @@ To start coding right away, check out the [Substreams Quick Start](/substreams/g Substreams is a powerful parallel blockchain indexing technology designed to enhance performance and scalability within The Graph Network. -## Substreams Capabilities +## Substreams Benefits - **Accelerated Indexing**: Boost subgraph indexing time with a parallelized engine for quicker data retrieval and processing. - **Multi-Chain Support**: Expand indexing capabilities beyond EVM-based chains, supporting ecosystems like Solana, Injective, Starknet, and Vara. diff --git a/website/src/_app.tsx b/website/src/_app.tsx index 16d41660241e..15238280d6ec 100644 --- a/website/src/_app.tsx +++ b/website/src/_app.tsx @@ -193,7 +193,7 @@ function Layout({ showLocaleSwitcher, children }: PropsWithChildren<{ showLocale placeholder={t('docsearch.button.buttonText')} /> {showLocaleSwitcher ? ( - + ) : null} {defaultContentAfter} From c3636eab2ad1a390180dc7a7a68a64b282e7f2bd Mon Sep 17 00:00:00 2001 From: Idalith Bustos Date: Mon, 27 Jan 2025 13:13:27 -0800 Subject: [PATCH 19/20] fix --- website/pages/en/sps/introduction.mdx | 2 +- website/pages/en/substreams/introduction.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/pages/en/sps/introduction.mdx b/website/pages/en/sps/introduction.mdx index a084cf3cdd9c..a4959772e560 100644 --- a/website/pages/en/sps/introduction.mdx +++ b/website/pages/en/sps/introduction.mdx @@ -2,7 +2,7 @@ title: Introduction to Substreams-Powered Subgraphs --- -Boost your subgraph’s efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. +Boost your subgraph's efficiency and scalability by using [Substreams](/substreams/introduction/) to stream pre-indexed blockchain data. ## Overview diff --git a/website/pages/en/substreams/introduction.mdx b/website/pages/en/substreams/introduction.mdx index 95567b7ed53d..088188773a08 100644 --- a/website/pages/en/substreams/introduction.mdx +++ b/website/pages/en/substreams/introduction.mdx @@ -37,7 +37,7 @@ fn get_my_block(blk: Block) -> Result { 3. The WASM container is sent to a Substreams endpoint for execution. The Substreams provider feeds the WASM container with the blockchain data and the transformations are applied. -4. You select a [sink](https://docs.substreams.dev/how-to-guides/sinks), a place where you want to send the transformed data (for example a SQL database or a Subgraph). +4. You select a [sink](https://docs.substreams.dev/how-to-guides/sinks), a place where you want to send the transformed data (such as a SQL database or a Subgraph). ## Additional Resources From 29bdd4cf4a7b411c9cf7f11b84813289c65a08a1 Mon Sep 17 00:00:00 2001 From: benface Date: Mon, 27 Jan 2025 18:45:21 -0500 Subject: [PATCH 20/20] `pnpm check:fix` --- website/src/_app.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/_app.tsx b/website/src/_app.tsx index 15238280d6ec..16d41660241e 100644 --- a/website/src/_app.tsx +++ b/website/src/_app.tsx @@ -193,7 +193,7 @@ function Layout({ showLocaleSwitcher, children }: PropsWithChildren<{ showLocale placeholder={t('docsearch.button.buttonText')} /> {showLocaleSwitcher ? ( - + ) : null} {defaultContentAfter}