{"id":20163214,"url":"https://github.com/blockdaemon/demo-event-streaming","last_synced_at":"2026-05-12T19:49:31.872Z","repository":{"id":232713209,"uuid":"785006025","full_name":"Blockdaemon/demo-event-streaming","owner":"Blockdaemon","description":"Blockdaemon Chain Watch - streaming on-chain events in real-time ","archived":false,"fork":false,"pushed_at":"2024-11-22T17:35:54.000Z","size":5,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-03T03:11:43.006Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Blockdaemon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-04-11T02:01:32.000Z","updated_at":"2024-11-22T17:35:58.000Z","dependencies_parsed_at":"2024-04-11T04:12:28.960Z","dependency_job_id":"eccafa13-1457-4118-b5d3-05c4c183f546","html_url":"https://github.com/Blockdaemon/demo-event-streaming","commit_stats":null,"previous_names":["blockdaemon/event-streaming-demo","blockdaemon/demo-event-streaming"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blockdaemon%2Fdemo-event-streaming","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blockdaemon%2Fdemo-event-streaming/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blockdaemon%2Fdemo-event-streaming/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blockdaemon%2Fdemo-event-streaming/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Blockdaemon","download_url":"https://codeload.github.com/Blockdaemon/demo-event-streaming/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241600493,"owners_count":19988715,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T00:28:38.340Z","updated_at":"2026-05-12T19:49:31.834Z","avatar_url":"https://github.com/Blockdaemon.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Blockdaemon Chain Watch - streaming on-chain events in real-time \n  - In this example we'll use the Event Streaming service to monitor any on-chain transfers to the PEPE smart contract\n  - Requirements:\n    - Go lang\n    - Blockdaemon REST API key\n    - Reverse proxy service\n    - [HTTPie](https://httpie.io/cli) \u0026 [jq](https://jqlang.github.io/jq/download/) CLI tools\n  - Docs: https://docs.blockdaemon.com/reference/events-introduction\n\n\n```mermaid\nsequenceDiagram\n    participant Customer\n    participant webhook as Customer Webhook\u003cbr\u003eServer\n    participant A as Event Streaming\u003cbr\u003eAPI\n    participant B as Blockdaemon\u003cbr\u003eIndexing Stack\n    participant C as RPC Node\u003cbr\u003eCluster\n    Customer-\u003e\u003eA: Create webhook target\n    A-\u003e\u003eA: Create target\n    A-\u003e\u003ewebhook: Target status connected\n    Customer-\u003e\u003eA: Create matching rule\n    A-\u003e\u003eB: Apply rule\n    loop\n        C-\u003e\u003eB: Consume blockchain data\n        B-\u003e\u003eA: Adds messages to target topic\n    end\n    loop\n        A-\u003e\u003eA: Read messages for rule\n        A-\u003e\u003ewebhook: Send formatted message to target\n    end\n```\n\n## Step 1. Run webhook receiver (includes a Challenge Response Check)\n  - the sample webhook server will respond to CRC token checks with the secret \"mysecret123\"\n  - all webhook posts will be printed to the console\n  - the service will listen on port 8082\n```shell\ngo run webhookserver.go\n```\n\n## Step 2. Publish the webhook server socket\n  - [ngrok reverse proxy](https://ngrok.com/docs/getting-started/) is used as an example to publish the server\n  - register for ngrok account or publish through your own methods\n```shell\n# set the Webhook Server FQDN\nexport WEBHOOKSERVERFQDN=XXXX.ngrok-free.app\n\n# start the reverse proxy\nngrok http --domain=$WEBHOOKSERVERFQDN http://localhost:8082\n```\n\n## Step 3. \n\n```shell\n# set Blockdaemon API key variable\nexport XAPIKey=XXXXX\n\n# note Event Streaming protocol capabilities\nhttp GET https://svc.blockdaemon.com/streaming/v2/ \\\n  X-Api-Key:$XAPIKey\n\n# create webhook target - set the ngrok domain and note secret matches webhook server\nTARGET_ID=$(http POST https://svc.blockdaemon.com/streaming/v2/targets \\\n    X-Api-Key:$XAPIKey \\\n    name='smartcontract webhook target' \\\n    description='Sample Go Webhookserver target' \\\n    max_buffer_count:=100 \\\n    settings:='{\"destination\": \"https://'\"$WEBHOOKSERVERFQDN\"'\", \"method\": \"POST\", \"secret\": \"mysecret123\"}' \\\n    type='webhook' \\\n    | jq -r .id)\n\n# get the webhook target status - should be \"connected\"\nhttp GET https://svc.blockdaemon.com/streaming/v2/targets \\\n    X-Api-Key:$XAPIKey \n```\n## Step 4.\n```shell\n# create a smart contract address variable key\nVARIABLE_ID=$(http POST https://svc.blockdaemon.com/streaming/v2/variables \\\n    X-Api-Key:$XAPIKey \\\n    name='smart contract addresses' \\\n    description='smart contract addresses' \\\n    type='string' \\\n    | jq -r .id)\n\n# set the variable key value to the PEPE token contract address 0x6982508145454Ce325dDbE47a25d4ec3d2311933\nhttp POST https://svc.blockdaemon.com/streaming/v2/variables/$VARIABLE_ID/values \\\n    X-Api-Key:$XAPIKey \\\n    value='0x6982508145454Ce325dDbE47a25d4ec3d2311933'\n```\n## Step 5.\n```shell\n# create rule combining the webhook target, the blockchain (Ethereum Mainnet), and the target address\n# review the different output template options here: https://docs.blockdaemon.com/docs/advanced-templating#using-predefined-templates\nRULE_ID=$(http POST https://svc.blockdaemon.com/streaming/v2/rules \\\n    X-Api-Key:$XAPIKey \\\n    name='Ethereum mainnet rule' \\\n    description='Ethereum mainnet rule' \\\n    network='mainnet' \\\n    protocol='ethereum' \\\n    condition:='[{\"variable_type\": \"address\", \"variable_id\": \"'\"$VARIABLE_ID\"'\"}]' \\\n    target=\"$TARGET_ID\" \\\n    condition_type='match_var' \\\n    is_active:=true \\\n    template='UNIFIED_V1' \\\n    | jq -r .id)\n\n# validate the rule\nhttp GET https://svc.blockdaemon.com/streaming/v2/rules \\\n    X-Api-Key:$XAPIKey\n```\n\n## Step 6.\nObserve the different webhook events in the webhookserver output. Example below of confirmed_tx event:\n```json\n{\n  \"data\": {\n    \"accessList\": [],\n    \"additionalFields\": {\n      \"yParity\": \"0x0\"\n    },\n    \"blockHash\": \"0xfc57c0ce8f94d133863f21dda0943b553e792e5fd1b9e687c680aa1b286bfd1f\",\n    \"blockNumber\": \"0x12b845b\",\n    \"chainId\": \"0x1\",\n    \"contractAddress\": null,\n    \"creates\": null,\n    \"cumulativeGasUsed\": \"0x1bfc64d\",\n    \"effectiveGasPrice\": \"0x2bad348ab\",\n    \"from\": \"0xcAFb5420CE411476ef43CCeEa50e71A95b6Ad5B0\",\n    \"gas\": \"0x163ed\",\n    \"gasPrice\": \"0x2bad348ab\",\n    \"gasUsed\": \"0xd986\",\n    \"hash\": \"0x06424f8c03c746ea1ccf3167d454a4ca54351bb4b179c9b3803455872cc31248\",\n    \"input\": \"0xa9059cbb00000000000000000000000031da1b45d2570b5722618b8b43b0c805114048ee00000000000000000000000000000000000000000031c7ea725f3bca431e6000\",\n    \"logsBloom\": \"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000008000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000010000004000000000000000000000000000000000000000000000000000000000200000000000040000000000000000000000000000000002000000000000000000000000000000002000000000400000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000008000\",\n    \"maxFeePerGas\": \"0x40c933ae2\",\n    \"maxPriorityFeePerGas\": \"0xecd10\",\n    \"nonce\": \"0x3d6\",\n    \"publicKey\": null,\n    \"r\": \"0x2b12ee7984f96db6cf16a190e257caa0392fa8961243488ff07caa4931adaffe\",\n    \"raw\": null,\n    \"root\": null,\n    \"s\": \"0x6ed8f306cdfa24c4aea4f30ec5cfb853dfe90adc6d32db37d60195e36e3b1422\",\n    \"status\": \"0x1\",\n    \"timestamp\": 1712799383,\n    \"to\": \"0x6982508145454Ce325dDbE47a25d4ec3d2311933\",\n    \"transactionIndex\": \"0xd0\",\n    \"type\": \"0x2\",\n    \"uuid\": \"8e695b82-7ed3-4ab0-894d-bce7a91077a6\",\n    \"v\": \"0x0\",\n    \"value\": \"0x0\"\n  },\n  \"event_type\": \"confirmed_tx\",\n  \"network\": \"mainnet\",\n  \"protocol\": \"ethereum\",\n  \"rule_id\": \"34b775e7-4425-4487-9181-0436022588fc\",\n  \"target_id\": \"9c6b6a09-dd23-40b7-bb57-7aa0673f2a20\"\n}\n```\nwhere:\n```json\ndata.input: 0xa9059cbb00000000000000000000000031da1b45d2570b5722618b8b43b0c805114048ee00000000000000000000000000000000000000000031c7ea725f3bca431e6000\n```\nABI decodes to:\n```json\n      \"definition\": \"transfer(address,uint256)\",\n      \"decodedInputs\": [\n        \"0x31DA1B45d2570B5722618B8b43b0C805114048EE\",\n        \"60181440870692720000000000\"\n      ]\n```\nmeaning `60181440870692720000000000` PEPE was transferred from `0xcAFb5420CE411476ef43CCeEa50e71A95b6Ad5B0` to `0x31DA1B45d2570B5722618B8b43b0C805114048EE`\n\n## Step 7.\n```shell\n# terminate the reverse proxy to simulate real-world failure and observe the current_buffer_count increase\nhttp GET https://svc.blockdaemon.com/streaming/v2/targets \\\n    X-Api-Key:$XAPIKey \n[\n        ...\n        \"current_buffer_count\": 35,\n        \"description\": \"Sample Go Webhookserver target\",\n        ...\n]\n```\n\n\n## Step 8.\n```shell\n# delete the rule to halt further notifitions\nhttp DELETE https://svc.blockdaemon.com/streaming/v2/rules/$RULE_ID \\\n    X-Api-Key:$XAPIKey\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblockdaemon%2Fdemo-event-streaming","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblockdaemon%2Fdemo-event-streaming","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblockdaemon%2Fdemo-event-streaming/lists"}