{"id":21995369,"url":"https://github.com/blinklabs-io/adder","last_synced_at":"2026-03-02T22:14:04.958Z","repository":{"id":66340824,"uuid":"603269067","full_name":"blinklabs-io/adder","owner":"blinklabs-io","description":"Event-driven tool/library for tailing the Cardano blockchain","archived":false,"fork":false,"pushed_at":"2025-04-27T14:53:10.000Z","size":1103,"stargazers_count":34,"open_issues_count":21,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-27T15:42:32.063Z","etag":null,"topics":["blockchain","cardano","go","golang","ouroboros","ouroboros-network","toolbox"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/blinklabs-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-02-18T01:50:52.000Z","updated_at":"2025-04-27T14:53:13.000Z","dependencies_parsed_at":"2023-09-28T17:27:43.167Z","dependency_job_id":"3739592f-6bdd-445d-89bd-f4f05ca03ac2","html_url":"https://github.com/blinklabs-io/adder","commit_stats":{"total_commits":223,"total_committers":4,"mean_commits":55.75,"dds":0.5919282511210762,"last_synced_commit":"f05c5a693bad196e5ee61902cb12280916685779"},"previous_names":["blinklabs-io/adder","blinklabs-io/snek"],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blinklabs-io%2Fadder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blinklabs-io%2Fadder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blinklabs-io%2Fadder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blinklabs-io%2Fadder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blinklabs-io","download_url":"https://codeload.github.com/blinklabs-io/adder/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251750476,"owners_count":21637729,"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":["blockchain","cardano","go","golang","ouroboros","ouroboros-network","toolbox"],"created_at":"2024-11-29T21:14:36.687Z","updated_at":"2026-02-23T18:20:04.503Z","avatar_url":"https://github.com/blinklabs-io.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Adder\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"./.github/assets/adder-logo-with-text-horizontal.png\" alt=\"Adder Logo\" width=\"640\"\u003e\n\u003c/div\u003e\n\nAdder is a tool for tailing the Cardano blockchain and emitting events for each\nblock and transaction that it sees.\n\n## How it works\n\nInput can be a local or remote Cardano full node, using either NtC (local UNIX\nsocket, TCP over socat) or NtN to remote nodes.\n\nEvents are created with a simple schema.\n\n```json\n{\n  \"type\": \"event type\",\n  \"timestamp\": \"wall clock timestamp of event\",\n  \"context\": \"metadata about the event\",\n  \"payload\": \"the full event specific payload\"\n}\n```\n\nThe chainsync input produces four event types: `input.block`, `input.rollback`,\n`input.transaction`, and `input.governance`. Each type has a unique payload.\n\ninput.block:\n\n```json\n{\n  \"context\": {\n    \"blockNumber\": 123,\n    \"slotNumber\": 1234567\n  },\n  \"payload\": {\n    \"blockBodySize\": 123,\n    \"issuerVkey\": \"a712f81ab2eac...\",\n    \"blockHash\": \"abcd123...\",\n    \"blockCbor\": \"85828a1a000995c21...\"\n  }\n}\n```\n\ninput.rollback:\n\n```json\n{\n  \"payload\": {\n    \"blockHash\": \"abcd123...\",\n    \"slotNumber\": 1234567\n  }\n}\n```\n\ninput.transaction:\n\n```json\n{\n    \"context\": {\n        \"blockNumber\": 123,\n        \"slotNumber\": 1234567,\n        \"transactionHash\": \"0deadbeef123...\",\n        \"transactionIdx\": 0,\n    },\n    \"payload\": {\n        \"blockHash\": \"abcd123...\",\n        \"transactionCbor\": \"a500828258200a1ad...\"\n        \"inputs\": [\n          \"abcdef123...#0\",\n          \"abcdef123...#1\",\n        ],\n        \"outputs\": [\n            {\n                \"address\": \"addr1qwerty123...\",\n                \"amount\":  12345687,\n                \"assets\": [\n                    {\n                        \"name\": \"Foo\",\n                        \"nameHex\": \"abcd123...\",\n                        \"amount\": 123,\n                        \"fingerprint\": \"asset1abcd...\",\n                        \"policyId\": \"54321...\"\n                    }\n                ]\n            }\n        ],\n        \"metadata\": {\n            \"674\": {\n                \"msg\": [\n                    \"Test message\"\n                ]\n            }\n        },\n        \"fee\": 1234567,\n        \"ttl\": 123\n    }\n}\n```\n\ninput.governance:\n\n```json\n{\n    \"context\": {\n        \"transactionHash\": \"1234abcd1234abcd...\",\n        \"blockNumber\": 123,\n        \"slotNumber\": 1234567,\n        \"transactionIdx\": 0,\n        \"networkMagic\": 1\n    },\n    \"payload\": {\n        \"blockHash\": \"abcd123...\",\n        \"transactionCbor\": \"a500828258200a1ad...\",\n        \"proposalProcedures\": [\n            {\n                \"deposit\": 1000000000,\n                \"rewardAccount\": \"stake1u9abcd...\",\n                \"anchor\": {\n                    \"url\": \"https://example.com/proposal.json\",\n                    \"hash\": \"abcd1234...\"\n                },\n                \"action\": {\n                    \"parameterChange\": {\n                        \"govActionId\": {\n                            \"transactionId\": \"prev_tx_hash...\",\n                            \"govActionIdx\": 0\n                        },\n                        \"policyHash\": \"abcd1234...\"\n                    }\n                }\n            }\n        ],\n        \"votingProcedures\": [\n            {\n                \"voter\": \"drep1abcd...\",\n                \"voterType\": \"DRep\",\n                \"govActionId\": {\n                    \"transactionId\": \"action_tx_hash...\",\n                    \"govActionIdx\": 0\n                },\n                \"vote\": \"Yes\",\n                \"anchor\": {\n                    \"url\": \"https://example.com/vote-rationale.json\",\n                    \"hash\": \"efgh5678...\"\n                }\n            }\n        ],\n        \"drepCertificates\": [...],\n        \"voteDelegationCertificates\": [...],\n        \"committeeCertificates\": [...]\n    }\n}\n```\n\nEach event is output individually. The log output supports two formats:\n\n- **text** (default) — human-readable, one line per event:\n\n  ```text\n  2026-02-07 09:18:40 BLOCK        slot=12345678  block=9876543  hash=abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234 era=Conway  txs=5 size=1234\n  2026-02-07 09:18:41 TX           slot=12345678  block=9876543  tx=deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef fee=180000 inputs=2 outputs=3\n  2026-02-07 09:18:42 ROLLBACK     slot=12345678  hash=aabbccddaabbccddaabbccddaabbccddaabbccddaabbccddaabbccddaabbccdd\n  2026-02-07 09:18:43 GOVERNANCE   slot=12345678  block=9876543  tx=1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd proposals=1 votes=2 certs=1\n  ```\n\n- **json** — newline-delimited JSON, one JSON object per event (suitable for\n  piping to `jq` or other tooling):\n\n  ```json\n  {\"type\":\"input.block\",\"timestamp\":\"2026-02-07T09:18:40Z\",\"context\":{\"blockNumber\":9876543,\"slotNumber\":12345678},\"payload\":{\"blockHash\":\"abc12345...\"}}\n  ```\n\nSelect the format with `--output-log-format`:\n\n```bash\nadder --output-log-format json\n```\n\nEvent data is written to **stdout** and application logs are written to\n**stderr**. This means you can capture only event output:\n\n```bash\n# Save events to a file, see app logs in terminal\nadder \u003e events.txt\n\n# Pipe events to jq, suppress app logs\nadder --output-log-format json 2\u003e/dev/null | jq .\n\n# See only app logs, discard event data\nadder \u003e /dev/null\n```\n\n## Configuration\n\nAdder supports multiple configuration methods for versatility: commandline\narguments, YAML config file, and environment variables (in that order).\n\nYou can get a list of all available commandline arguments by using the\n`--help` flag.\n\n```bash\n$ ./adder --help\n\nUsage:\n  adder [flags]\n\nFlags:\n      --config string                 path to config file to load\n      --input string                  input plugin to use, 'list' to show available (default \"chainsync\")\n      --input-chainsync-address string\n                                      specifies the TCP address of the node to connect to\n...\n      --output string                 output plugin to use, 'list' to show available (default \"log\")\n      --output-log-format string      output format: \"text\" or \"json\" (default \"text\")\n      --output-log-level string       specifies the log level to use (default \"info\")\n  -h, --help                          help for adder\n```\n\nEach commandline argument (other than `-config`) has a corresponding environment\nvariable. For example, the `-input` option has the `INPUT` environment variable,\nthe `-input-chainsync-address` option has the `INPUT_CHAINSYNC_ADDRESS`\nenvironment variable, and `-output` has `OUTPUT`.\n\n### Environment Variables\n\nCore configuration options can be set using environment variables:\n\n- `INPUT` - Input plugin to use (default: \"chainsync\")\n- `OUTPUT` - Output plugin to use (default: \"log\")\n- `KUPO_URL` - URL for Kupo service integration\n- `LOGGING_LEVEL` - Log level (default: \"info\")\n- `API_ADDRESS` - API server listen address (default: \"0.0.0.0\")\n- `API_PORT` - API server port (default: 8080)\n- `DEBUG_ADDRESS` - Debug server address (default: \"localhost\")\n- `DEBUG_PORT` - Debug server port (default: 0)\n\nGenesis configuration can also be controlled via environment variables:\n\n**Network Transition:**\n\n- `SHELLEY_TRANS_EPOCH` - Epoch number when Shelley era begins (default: 208 for mainnet)\n\n**Byron Genesis:**\n\n- `BYRON_GENESIS_END_SLOT` - End slot for Byron era\n- `BYRON_GENESIS_EPOCH_LENGTH` - Slot length of Byron epochs (default: 21600)\n- `BYRON_GENESIS_BYRON_SLOTS_PER_EPOCH` - Byron slots per epoch\n\n**Shelley Genesis:**\n\n- `SHELLEY_GENESIS_EPOCH_LENGTH` - Slot length of Shelley epochs (default: 432000)\n\nYou can also specify each option in the config file.\n\n```yaml\ninput: chainsync\n\noutput: log\n```\n\nPlugin arguments can be specified under a special top-level key in the config\nfile.\n\n```yaml\nplugins:\n  input:\n    chainsync:\n      network: preview\n\n  output:\n    log:\n      level: info\n      format: text\n```\n\n## Filtering\n\nAdder supports filtering events before they are output using multiple criteria.\nAn event must match all configured filters to be emitted. Each filter supports\nspecifying multiple possible values separated by commas. When specifying\nmultiple values for a filter, only one of the values specified must match an\nevent.\n\nYou can get a list of all available filter options by using the `-h`/`-help`\nflag.\n\n```bash\n$ ./adder -h\nUsage of adder:\n...\n  -filter-address string\n        specifies address to filter on\n  -filter-asset string\n        specifies the asset fingerprint (asset1xxx) to filter on\n  -filter-policy string\n        specifies asset policy ID to filter on\n  -filter-type string\n        specifies event type to filter on\n...\n```\n\nMultiple filter options can be used together, and only events matching all\nfilters will be output.\n\n## Example usage\n\n### Native using remote node\n\n```bash\nexport INPUT_CHAINSYNC_NETWORK=preview\n./adder\n```\n\nAlternatively using equivalent commandline options:\n\n```bash\n./adder \\\n  -input-chainsync-network preview\n```\n\n### In Docker using local node\n\nFirst, follow the instructions for\n[Running a Cardano Node](https://github.com/blinklabs-io/docker-cardano-node#running-a-cardano-node)\nin Docker.\n\n```bash\ndocker run --rm -ti \\\n  -v node-ipc:/node-ipc \\\n  ghcr.io/blinklabs-io/adder:main\n```\n\n### Filtering\n\n#### Filtering on event type\n\nOnly output `input.transaction` event types\n\n```bash\nadder -filter-type input.transaction\n```\n\nOnly output `input.transaction` and `input.block` event types\n\n```bash\nadder -filter-type input.transaction,input.block\n```\n\n#### Filtering on asset policy\n\nOnly output transactions involving an asset with a particular policy ID\n\n```bash\nadder -filter-type input.transaction \\\n  -filter-policy 13aa2accf2e1561723aa26871e071fdf32c867cff7e7d50ad470d62f\n```\n\n#### Filtering on asset fingerprint\n\nOnly output transactions involving a particular asset\n\n```bash\nadder -filter-type input.transaction \\\n  -filter-asset asset108xu02ckwrfc8qs9d97mgyh4kn8gdu9w8f5sxk\n```\n\n#### Filtering on a policy ID and asset fingerprint\n\nOnly output transactions involving both a particular policy ID and a particular\nasset (which do not need to be related)\n\n```bash\nadder -filter-type input.transaction \\\n  -filter-asset asset108xu02ckwrfc8qs9d97mgyh4kn8gdu9w8f5sxk \\\n  -filter-policy 13aa2accf2e1561723aa26871e071fdf32c867cff7e7d50ad470d62f\n```\n\n#### Filtering on an address\n\nOnly output transactions with outputs matching a particular address\n\n```bash\nadder -filter-type input.transaction \\\n  -filter-address addr1qyht4ja0zcn45qvyx477qlyp6j5ftu5ng0prt9608dxp6l2j2c79gy9l76sdg0xwhd7r0c0kna0tycz4y5s6mlenh8pq4jxtdy\n```\n\n#### Filtering on a stake address\n\nOnly output transactions with outputs matching a particular stake address\n\n```bash\nadder -filter-type input.transaction \\\n  -filter-address stake1u9f9v0z5zzlldgx58n8tklphu8mf7h4jvp2j2gddluemnssjfnkzz\n```\n\n### Push notifications\n\nThe example shows how push notification output can be used with filtering\noptions. In this example, push notifications will be sent for the block events.\nPush notifications will be sent to the FCM `project_id` specified in the\n`serviceAccount.json` file. Please refer to the\n[adder-mobile README](https://github.com/blinklabs-io/adder-mobile) for more\ndetails on how to send push notifications to mobile.\n\n```bash\nadder -filter-type input.block \\\n  -output push \\\n  -output-push-serviceAccountFilePath /path/to/serviceAccount.json\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblinklabs-io%2Fadder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblinklabs-io%2Fadder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblinklabs-io%2Fadder/lists"}