Documentation Index
Fetch the complete documentation index at: https://docs.lasso.sh/llms.txt
Use this file to discover all available pages before exploring further.
Lasso supports Ethereum JSON-RPC subscriptions over WebSocket for real-time blockchain events. Use eth_subscribe to create subscriptions and eth_unsubscribe to cancel them.
Subscription Types
Lasso supports the following subscription types:
| Type | Description |
|------|-------------||
| newHeads | New block headers as they arrive |
| logs | Log events matching a filter |
Creating Subscriptions
Request:
{"jsonrpc":"2.0","method":"eth_subscribe","params":["newHeads"],"id":1}
Response:
{"jsonrpc":"2.0","id":1,"result":"0xabc123..."}
The result field contains the subscription ID. Save this ID to unsubscribe later.
Subscription Events:
As new blocks arrive, the server pushes events:
{
"jsonrpc":"2.0",
"method":"eth_subscription",
"params":{
"subscription":"0xabc123...",
"result":{
"parentHash":"0x...",
"sha3Uncles":"0x...",
"miner":"0x...",
"stateRoot":"0x...",
"transactionsRoot":"0x...",
"receiptsRoot":"0x...",
"logsBloom":"0x...",
"difficulty":"0x0",
"number":"0x8471c9a",
"gasLimit":"0x1c9c380",
"gasUsed":"0x5208",
"timestamp":"0x65f3a2b0",
"extraData":"0x...",
"mixHash":"0x...",
"nonce":"0x0000000000000000",
"baseFeePerGas":"0x7",
"hash":"0x..."
}
}
}
Subscribe to Logs
Request with filter:
{
"jsonrpc":"2.0",
"method":"eth_subscribe",
"params":[
"logs",
{
"address":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]
}
],
"id":2
}
This example subscribes to Transfer events from USDC on Ethereum.
Response:
{"jsonrpc":"2.0","id":2,"result":"0xdef456..."}
Subscription Events:
As matching logs are emitted, the server pushes events:
{
"jsonrpc":"2.0",
"method":"eth_subscription",
"params":{
"subscription":"0xdef456...",
"result":{
"address":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"topics":[
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000742d35cc6634c0532925a3b844bc454e4438f44e",
"0x0000000000000000000000001e0049783f008a0085193e00003d00cd54003c71"
],
"data":"0x0000000000000000000000000000000000000000000000000000000002faf080",
"blockNumber":"0x8471c9a",
"transactionHash":"0x...",
"transactionIndex":"0x0",
"blockHash":"0x...",
"logIndex":"0x0",
"removed":false
}
}
}
Log Filter Options
The logs subscription accepts a filter object with:
| Field | Type | Description |
|-------|------|-------------||
| address | string or array | Contract address(es) to filter. Omit for all contracts. |
| topics | array | Event signature and indexed parameters. Use null for wildcards. |
Examples:
All events from a contract:
{
"address":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
}
Specific event signature across all contracts:
{
"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]
}
Event from multiple contracts:
{
"address":[
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"0xdac17f958d2ee523a2206206994597c13d831ec7"
],
"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]
}
Event with indexed parameter filter:
{
"address":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"topics":[
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
null,
"0x0000000000000000000000001e0049783f008a0085193e00003d00cd54003c71"
]
}
This filters for Transfer events where the second indexed parameter (recipient) matches the specified address.
Unsubscribing
Cancel a subscription using eth_unsubscribe:
Request:
{"jsonrpc":"2.0","method":"eth_unsubscribe","params":["0xabc123..."],"id":3}
Response:
{"jsonrpc":"2.0","id":3,"result":true}
A result of true indicates successful unsubscription. After unsubscribing, no more events will be pushed for that subscription ID.
Full Example
Here’s a complete subscription flow using wscat:
# Connect to WebSocket endpoint
wscat -c 'ws://localhost:4000/ws/rpc/ethereum?key=lasso_abc123'
# Subscribe to new blocks
> {"jsonrpc":"2.0","method":"eth_subscribe","params":["newHeads"],"id":1}
< {"jsonrpc":"2.0","id":1,"result":"0xabc123..."}
# Receive block events
< {"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0xabc123...","result":{...}}}
< {"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0xabc123...","result":{...}}}
# Unsubscribe
> {"jsonrpc":"2.0","method":"eth_unsubscribe","params":["0xabc123..."],"id":2}
< {"jsonrpc":"2.0","id":2,"result":true}
Subscription Lifecycle
Automatic Cleanup
Subscriptions are automatically cleaned up when:
- The WebSocket connection closes
- The connection times out (see Connection Lifecycle)
- An
eth_unsubscribe request is received
Multiple Subscriptions
You can create multiple subscriptions on a single WebSocket connection:
// Subscribe to blocks
{"jsonrpc":"2.0","method":"eth_subscribe","params":["newHeads"],"id":1}
// Subscribe to logs
{"jsonrpc":"2.0","method":"eth_subscribe","params":["logs",{"address":"0x..."}],"id":2}
Each subscription receives a unique subscription ID and events are tagged with the corresponding ID.
Error Handling
Invalid Subscription Type
Request:
{"jsonrpc":"2.0","method":"eth_subscribe","params":["invalidType"],"id":1}
Response:
{
"jsonrpc":"2.0",
"id":1,
"error":{
"code":-32602,
"message":"Invalid params: unsupported subscription type"
}
}
Request:
{"jsonrpc":"2.0","method":"eth_subscribe","params":["logs",{"invalid":"field"}],"id":2}
Response:
{
"jsonrpc":"2.0",
"id":2,
"error":{
"code":-32602,
"message":"Invalid params: malformed filter"
}
}
Unsubscribe Non-Existent Subscription
Request:
{"jsonrpc":"2.0","method":"eth_unsubscribe","params":["0xnonexistent"],"id":3}
Response:
{"jsonrpc":"2.0","id":3,"result":false}
A result of false indicates the subscription ID was not found.
Best Practices
Track Subscription IDs
Always store subscription IDs returned by eth_subscribe to unsubscribe later:
const subscriptionIds = new Map();
// Subscribe
const request = {jsonrpc: "2.0", method: "eth_subscribe", params: ["newHeads"], id: 1};
ws.send(JSON.stringify(request));
ws.on('message', (data) => {
const response = JSON.parse(data);
if (response.id === 1) {
subscriptionIds.set('newHeads', response.result);
}
});
// Unsubscribe
function cleanup() {
const subId = subscriptionIds.get('newHeads');
if (subId) {
const request = {jsonrpc: "2.0", method: "eth_unsubscribe", params: [subId], id: 2};
ws.send(JSON.stringify(request));
}
}
Handle Reconnection
Subscriptions don’t persist across reconnections. Re-subscribe after reconnecting:
ws.on('open', () => {
// Re-subscribe to all active subscriptions
subscribeToNewHeads();
subscribeToLogs();
});
Filter Logs Efficiently
Use specific filters to reduce network traffic:
// Good: Specific contract and event
{
"address":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]
}
// Avoid: No filter (receives all logs)
{}
Rate Limiting
Subscriptions count toward your API rate limit. Monitor your usage and adjust filters accordingly.