-
Notifications
You must be signed in to change notification settings - Fork 25
Add Linea tooling + tutorial #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| --- | ||
| title: "Chainstack updates: June 9, 2025" | ||
| --- | ||
| **Protocols**. Now, you can deploy [Global Nodes](/docs/global-elastic-node) for Linea Mainnet. | ||
| **Protocols**. Now, you can deploy [Global Nodes](/docs/global-elastic-node) for Linea Mainnet. See also [Linea tooling](/docs/linea-tooling) and a [tutorial](/docs/linea-real-time-transaction-monitor-python). | ||
|
Check warning on line 4 in changelog/chainstack-updates-june-9-2025.mdx
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| --- | ||
| title: "Linea: Real-time transaction activity monitor with Python" | ||
| description: "Learn how to build a real-time transaction activity monitor for Linea blockchain using Python and web3.py through Chainstack RPC endpoints." | ||
|
Check warning on line 3 in docs/linea-real-time-transaction-monitor-python.mdx
|
||
| --- | ||
|
|
||
| **TLDR:** | ||
|
|
||
| * Demonstrates building a real-time transaction activity monitor for Linea blockchain using Python and web3.py | ||
|
Check warning on line 8 in docs/linea-real-time-transaction-monitor-python.mdx
|
||
| * Shows how to handle Proof-of-Authority (POA) networks with proper middleware configuration in web3.py | ||
| * Includes practical examples of block polling and transaction analysis | ||
|
|
||
| ## Overview | ||
|
|
||
| Linea is a high-performance Layer 2 blockchain that offers fast transaction processing with approximately 2-second block times. | ||
|
Check warning on line 14 in docs/linea-real-time-transaction-monitor-python.mdx
|
||
|
|
||
| This tutorial is a very easy quickstart guide to create a real-time transaction monitor that visualizes blockchain activity as it happens. You'll learn how to connect to the Linea mainnet and efficiently poll the chain. How to handle POA networks correctly, and create beautiful terminal interfaces that provide instant insights into network activity. | ||
|
Check warning on line 16 in docs/linea-real-time-transaction-monitor-python.mdx
|
||
|
|
||
| ## Prerequisites | ||
|
|
||
| - [web3.py](https://web3py.readthedocs.io/) | ||
| - A Chainstack Linea Mainnet node endpoint—register on [Chainstack](https://console.chainstack.com/) | ||
|
Check warning on line 21 in docs/linea-real-time-transaction-monitor-python.mdx
|
||
|
|
||
| ## Understanding Linea | ||
|
|
||
| Linea is a Layer 2 rollup to Ethereum developed by Consensys. | ||
|
Check warning on line 25 in docs/linea-real-time-transaction-monitor-python.mdx
|
||
|
|
||
| Linea is fully EVM compatible and has a fast block time of approximately 2 seconds. | ||
|
|
||
| Linea is also a zero-knowledge (zk) rollup. | ||
|
Check warning on line 29 in docs/linea-real-time-transaction-monitor-python.mdx
|
||
|
|
||
| ## Live transaction monitor | ||
|
|
||
| Now let's create a simple live transaction monitor script. | ||
|
|
||
| The script connects to the Linea mainnet over a Chainstack Linea node RPC endpoint. Then the script polls the mainnet chain for each new block as it comes in, checks the number of transactions and prints the data in the terminal along with the adjustable visuals for easy viewing. | ||
|
Check warning on line 35 in docs/linea-real-time-transaction-monitor-python.mdx
|
||
|
|
||
| This is an easy tutorial script, so the main goal here is to check: | ||
|
|
||
| * How to use web3.py | ||
| * How to connect to the Linea mainnet | ||
|
Check warning on line 40 in docs/linea-real-time-transaction-monitor-python.mdx
|
||
| * How to handle POA networks correctly | ||
| * How to poll the chain for new blocks and extract the number of transactions | ||
|
|
||
| Here's the full script: | ||
|
|
||
| ```python | ||
| import asyncio, math | ||
| from web3 import AsyncHTTPProvider, AsyncWeb3 | ||
| from web3.middleware import ExtraDataToPOAMiddleware | ||
| from rich.console import Console | ||
| from rich.text import Text | ||
|
|
||
| # Chainstack Linea mainnet endpoint | ||
| RPC = "YOUR_CHAINSTACK_ENDPOINT" | ||
|
|
||
| w3 = AsyncWeb3(AsyncHTTPProvider(RPC)) | ||
| # Add POA middleware for Linea | ||
| w3.middleware_onion.inject(ExtraDataToPOAMiddleware, layer=0) | ||
| c = Console() | ||
|
|
||
| # Tweak these bands to taste (transaction counts) | ||
| BANDS = [5, 20, 50, 100] # quiet > busy (transactions per block) | ||
| BAR_LEN = 30 # number of "pixels" | ||
|
|
||
| def mood_color(tx_count: int) -> str: | ||
| if tx_count < BANDS[0]: return "green" | ||
| if tx_count < BANDS[1]: return "bright_green" | ||
| if tx_count < BANDS[2]: return "yellow" | ||
| if tx_count < BANDS[3]: return "orange" | ||
| return "red" | ||
|
|
||
| def mood_bar(tx_count: int) -> Text: | ||
| # % of BAR_LEN that should be "hot" | ||
| pct = min(tx_count / BANDS[-1], 1.0) | ||
| hot = math.ceil(pct * BAR_LEN) | ||
| bar = Text() | ||
| for i in range(BAR_LEN): | ||
| color = "white" | ||
| if i < hot: | ||
| color = mood_color(tx_count) | ||
| bar.append("█", style=color) | ||
| return bar | ||
|
|
||
| async def poll(): | ||
| # Get initial block number | ||
| last_block_number = None | ||
|
|
||
| while True: | ||
| # Get latest block header | ||
| blk = await w3.eth.get_block("latest") | ||
|
|
||
| # Only process if it's a new block | ||
| if last_block_number is None or blk.number > last_block_number: | ||
| last_block_number = blk.number | ||
|
|
||
| # Count transactions in this block | ||
| tx_count = len(blk.transactions) | ||
|
|
||
| line = Text.assemble( | ||
| ("blk ", "cyan"), (str(blk.number).ljust(8), "bold cyan"), | ||
| (" | txs ", "grey50"), (f"{tx_count}".ljust(11), "bold"), | ||
| (" | ", "grey50"), mood_bar(tx_count) | ||
| ) | ||
| yield line | ||
|
|
||
| # Check for new blocks more frequently (Linea has ~2 second block times) | ||
| await asyncio.sleep(1) | ||
|
|
||
| async def main(): | ||
| c.print("[dim]Powered by Chainstack—spin up your own Linea endpoint in 30s[/]") | ||
| c.print("[bold cyan]🎯 Linea transaction activity monitor[/]") | ||
| c.print() | ||
|
|
||
| async for txt in poll(): | ||
| c.print(txt) | ||
|
|
||
| asyncio.run(main()) | ||
| ``` | ||
|
|
||
| ## Conclusion | ||
|
|
||
| This tutorial provided a comprehensive guide to building real-time blockchain monitoring applications for Linea using Python. | ||
|
Check warning on line 122 in docs/linea-real-time-transaction-monitor-python.mdx
|
||
|
|
||
| The monitoring approach demonstrated here can be easily extended to track specific contracts, tokens, or transaction patterns. | ||
|
|
||
| <Info> | ||
| ### See also | ||
|
|
||
| <CardGroup> | ||
| <Card title="Linea documentation" href="https://docs.linea.build/" icon="angle-right" horizontal /> | ||
| <Card title="web3.py documentation" href="https://web3py.readthedocs.io/" icon="angle-right" horizontal /> | ||
| </CardGroup> | ||
| </Info> | ||
|
|
||
| ### About the author | ||
|
|
||
| <CardGroup> | ||
| <Card title="Ake" img="/images/docs/profile_images/1719912994363326464/8_Bi4fdM_400x400.jpg"> | ||
| <Icon icon="code" iconType="solid"/>Director of Developer Experience @ Chainstack | ||
|
|
||
| <Icon icon="screwdriver-wrench" iconType="solid"/> Talk to me all things Web3 | ||
|
|
||
| 20 years in technology | 8+ years in Web3 full time years experience | ||
|
|
||
| Trusted advisor helping developers navigate the complexities of blockchain infrastructure | ||
|
|
||
| [<Icon icon="github" iconType="brands"/>](https://github.com/akegaviar/) | ||
| [<Icon icon="twitter" iconType="brands"/>](https://twitter.com/akegaviar) | ||
| [<Icon icon="linkedin" iconType="brands"/>](https://www.linkedin.com/in/ake/) | ||
| [<Icon icon="warpcast" iconType="brands"/>](https://warpcast.com/ake) | ||
| </Card> | ||
| </CardGroup> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,182 @@ | ||
| --- | ||
| title: "Linea tooling" | ||
| --- | ||
|
|
||
| ## MetaMask | ||
|
|
||
| On [node access details](/docs/manage-your-node#view-node-access-and-credentials), click **Add to MetaMask**. | ||
|
|
||
| ## web3.py | ||
|
|
||
| Build DApps using [web3.py](https://github.com/ethereum/web3.py) and Linea nodes deployed with Chainstack. | ||
|
Check warning on line 11 in docs/linea-tooling.mdx
|
||
| <Steps> | ||
| <Step> | ||
| Install [web3.py](https://web3py.readthedocs.io/). | ||
| </Step> | ||
| <Step> | ||
| Connect over HTTP. See also [EVM node connection: HTTP vs WebSocket](https://support.chainstack.com/hc/en-us/articles/900002187586-Ethereum-node-connection-HTTP-vs-WebSocket). | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| ### HTTP | ||
|
|
||
| Use the `HTTPProvider` to connect to your node endpoint and get the latest block number. | ||
|
|
||
| <CodeGroup> | ||
| ```python Key Protected | ||
| from web3 import Web3 | ||
|
|
||
| web3 = Web3(Web3.HTTPProvider('YOUR_CHAINSTACK_ENDPOINT')) | ||
| print(web3.eth.block_number) | ||
| ``` | ||
|
|
||
| ```python Password Protected | ||
| from web3 import Web3 | ||
|
|
||
| web3 = Web3(Web3.HTTPProvider('https://%s:%s@%s'% ("USERNAME", "PASSWORD", "HOSTNAME"))) | ||
| print(web3.eth.block_number) | ||
| ``` | ||
| </CodeGroup> | ||
|
|
||
| where | ||
|
|
||
| * YOUR\_CHAINSTACK\_ENDPOINT — your node HTTPS endpoint protected either with the key or password | ||
|
|
||
| See also [node access details](/docs/manage-your-node#view-node-access-and-credentials). | ||
|
|
||
| ## ethers.js | ||
|
|
||
| Build DApps using [ethers.js](https://github.com/ethers-io/ethers.js/) and Linea nodes deployed with Chainstack. | ||
|
Check warning on line 49 in docs/linea-tooling.mdx
|
||
| <Steps> | ||
| <Step> | ||
| Install [ethers.js](https://www.npmjs.com/package/ethers). | ||
| </Step> | ||
| <Step> | ||
| Connect over HTTP. See also [EVM node connection: HTTP vs WebSocket](https://support.chainstack.com/hc/en-us/articles/900002187586-Ethereum-node-connection-HTTP-vs-WebSocket). | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| ### HTTP | ||
|
|
||
| Use the `JsonRpcProvider` object to connect to your node endpoint and get the latest block number: | ||
|
|
||
| <CodeGroup> | ||
| ```javascript Key Protected | ||
| const { ethers } = require("ethers"); | ||
|
|
||
| var urlInfo = { | ||
| url: 'YOUR_CHAINSTACK_ENDPOINT' | ||
| }; | ||
| var provider = new ethers.JsonRpcProvider(urlInfo.url, NETWORK_ID); | ||
|
|
||
| provider.getBlockNumber().then(console.log); | ||
| ``` | ||
| </CodeGroup> | ||
|
akegaviar marked this conversation as resolved.
|
||
|
|
||
| where | ||
|
|
||
| * YOUR\_CHAINSTACK\_ENDPOINT — your node HTTPS endpoint protected either with the key or password | ||
|
|
||
| * NETWORK\_ID — Linea network ID: | ||
|
|
||
| * Mainnet: `59144` | ||
|
|
||
|
akegaviar marked this conversation as resolved.
|
||
|
|
||
| See also [node access details](/docs/manage-your-node#view-node-access-and-credentials). | ||
|
|
||
| ## Hardhat | ||
|
|
||
| Configure [Hardhat](https://hardhat.org/) to deploy contracts and interact through your Linea nodes. | ||
|
|
||
| <Steps> | ||
| <Step> | ||
| Install [Hardhat](https://hardhat.org/) and create a project. | ||
| </Step> | ||
| <Step> | ||
| Create a new environment in `hardhat.config.js`: | ||
|
|
||
| <CodeGroup> | ||
| ```javascript Javascript | ||
| require("@nomiclabs/hardhat-waffle"); | ||
| ... | ||
| module.exports = { | ||
| solidity: "0.7.3", | ||
| networks: { | ||
| chainstack: { | ||
| url: "YOUR_CHAINSTACK_ENDPOINT", | ||
| accounts: ["YOUR_PRIVATE_KEY"] | ||
| }, | ||
| } | ||
| }; | ||
| ``` | ||
| </CodeGroup> | ||
|
|
||
| where | ||
|
|
||
| * YOUR\_CHAINSTACK\_ENDPOINT — your node HTTPS or WSS endpoint protected either with the key or password. See [node access details](/docs/manage-your-node#view-node-access-and-credentials). | ||
| * YOUR\_PRIVATE\_KEY — the private key of the account that you use to deploy the contract | ||
| </Step> | ||
| <Step> | ||
| Run `npx hardhat run scripts/deploy.js --network chainstack` and Hardhat will deploy using Chainstack. | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| See also [Forking EVM-compatible mainnet with Hardhat](https://support.chainstack.com/hc/en-us/articles/900004242406). | ||
|
|
||
| ## Remix IDE | ||
|
|
||
| To make Remix IDE interact with the network through a Chainstack node: | ||
| <Steps> | ||
| <Step> | ||
| Get [MetaMask](https://metamask.io/) and set it to interact through a Chainstack node. See [Interacting through MetaMask](#metamask). | ||
| </Step> | ||
| <Step> | ||
| In Remix IDE, navigate to the **Deploy** tab. Select **Injected Provider - MetaMask** in **Environment**. | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| This will engage MetaMask and make Remix IDE interact with the network through a Chainstack node. | ||
|
|
||
| ## Foundry | ||
|
|
||
| <Steps> | ||
| <Step> | ||
| Install [Foundry](https://getfoundry.sh/). | ||
| </Step> | ||
| <Step> | ||
| Use `--rpc-url` to run the operation through your Chainstack node. | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| ### Forge | ||
|
|
||
| Use `forge` to develop, test, and deploy your smart contracts. | ||
|
|
||
| To deploy a contract: | ||
|
|
||
| <CodeGroup> | ||
| ```shell Shell | ||
| forge create CONTRACT_NAME --contracts CONTRACT_PATH --private-key YOUR_PRIVATE_KEY --rpc-url YOUR_CHAINSTACK_ENDPOINT | ||
| ``` | ||
| </CodeGroup> | ||
|
|
||
| where | ||
|
|
||
| * CONTRACT\_NAME — name of the contract in the Solidity source code | ||
| * CONTRACT\_PATH — path to your smart contract | ||
| * YOUR\_PRIVATE\_KEY — the private key to your funded account that you will use to deploy the contract | ||
| * YOUR\_CHAINSTACK\_ENDPOINT — your node HTTPS endpoint protected either with the key or password | ||
|
|
||
| ### Cast | ||
|
|
||
| Use `cast` to interact with the network and the deployed contracts. | ||
|
|
||
| To get the latest block number: | ||
|
|
||
| <CodeGroup> | ||
| ```shell Shell | ||
| cast block-number --rpc-url YOUR_CHAINSTACK_ENDPOINT | ||
| ``` | ||
| </CodeGroup> | ||
|
|
||
| where YOUR\_CHAINSTACK\_ENDPOINT is your node HTTPS endpoint protected either with the key or password | ||
Uh oh!
There was an error while loading. Please reload this page.