{"id":13515820,"url":"https://github.com/stellar-expert/operations-notifier","last_synced_at":"2025-03-31T05:31:00.326Z","repository":{"id":41490063,"uuid":"131706057","full_name":"stellar-expert/operations-notifier","owner":"stellar-expert","description":"A standalone service that tracks Stellar Network operations and streams notifications to the subscribers.","archived":false,"fork":false,"pushed_at":"2020-04-02T21:43:44.000Z","size":125,"stargazers_count":25,"open_issues_count":7,"forks_count":11,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-01T20:35:58.517Z","etag":null,"topics":["notifier","stellar","stellar-network"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stellar-expert.png","metadata":{"files":{"readme":"README.MD","changelog":"HISTORY.MD","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-05-01T11:34:36.000Z","updated_at":"2024-03-04T14:03:55.000Z","dependencies_parsed_at":"2022-09-21T10:31:21.799Z","dependency_job_id":null,"html_url":"https://github.com/stellar-expert/operations-notifier","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stellar-expert%2Foperations-notifier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stellar-expert%2Foperations-notifier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stellar-expert%2Foperations-notifier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stellar-expert%2Foperations-notifier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stellar-expert","download_url":"https://codeload.github.com/stellar-expert/operations-notifier/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246423527,"owners_count":20774795,"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":["notifier","stellar","stellar-network"],"created_at":"2024-08-01T05:01:16.335Z","updated_at":"2025-03-31T05:30:59.836Z","avatar_url":"https://github.com/stellar-expert.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Stellar Operations Notifier\n\nA standalone service that tracks Stellar Network operations and streams\nnotifications to the subscribers. The notifications are delivered as\nJSON-encoded HTTP POST requests. \n    \n### Highlights\n\n- Highly configurable.\n- Supports operations filtering by account, asset, transaction memo, and \noperation type. \n- Guaranteed delivery, even if the notification recipient or the Notifier itself\nis down for some time.\n- Supports public and private Stellar networks.\n- Can be used as a shared microservice that streams events to multiple endpoints.\n- Predictable performance – tested with thousands of subscriptions.\n- Reliable tracking and consistency (tracking is resumed from the same\ntransaction after restart).\n- Does not require Stellar Core or Horizon node deployment.\n- Notifications are signed with an ED25519 secret key to protect the recipient\nfrom spoofing.\n\n### So... Where can I use it?\n\n- **Payment processing**.\\\nNever miss a payment, even if a user decided to pay one week later, or you have\nsome troubles with your server.\n- **Anchors and ICOs**.\\\nImplement complex scenarios for your assets and track all user accounts. Track\nall operations involving your asset to gather statistics or calculate dividends.\n- **Trading platforms**.\\\nObserve trading activity, aggregate market data, gather statistics, build\nmarket-making applications.\n- **Monitoring tools**.\\\nKeep an eye on specific accounts or your favorite assets. Without pooling and\nother inefficient techniques.\n- **Inflation pools**.\\\nSubscribe to inflation operation and distribute rewards when the subscription\nwas triggered.\n- And more...  \n\n## System requirements\n\n#### Stellar Horizon server\n\nNotifier relies on an event stream from Horizon server, so you'll need to choose\na public Horizon service\n(like https://horizon.stellar.org and https://horizon-testnet.stellar.org/), or\nyou own hosted Horizon instance. The latter option is preferable for production\nsetups. Nevertheless, public Horizon instances supported by SDF and other\ncommunity members work just fine as well.\n\n#### NodeJS 8.6.0+\n\nThe service requires NodeJS 8.6.0 or later. \n\n#### (Optional) MongoDB 3.2+ or other storage provider\n\nFor the production deployment all notification queues are stored in the database.\n\nMongoDB was selected as the most convenient option in terms of fast read/writes\nalongside with minimum memory/IO overhead. \n\n#### Supported platforms\n\nLinux, Windows, MacOS.  \nEffectively any other platforms where you can run NodeJS and MongoDB.\n\n#### Docker\n\nDocker image by [@sgehrman](https://github.com/sgehrman) can be found\n[here](https://github.com/StellarKit/stellar-notifier-docker).\n\n## Installation\n\n1\\. Clone the repository.\n\n```\ngit clone https://github.com/stellar-expert/operations-notifier\n```\n\n2\\. Install required NPM packages.\n\n```\ncd operations-notifier\nnpm i\n```\n\n3\\. (For production deployments)\nEnsure that MongoDB is running. \nDownload it [here](https://www.mongodb.com/download-center?jmp=nav#community)\nin case if it has not been installed yet.\n\n4\\. Set configuration parameters in `app.config.json` (see\n[Configuration](#configuration) section).\n\n5\\. Start the service.\n\n```\nnpm run start\n```\n\n## Configuration\n\nAll configuration parameters are located in `app.config.json` file.\nThe server also supports setting parameters using environment variables.\nBy default the server loads settings from `app.config.json` file, and\noverwrites specific parameter if the corresponding environment variable found. \n\n- **storageProvider**\\\nStorage provider for persistence layer (see details in\n[Storage providers](#storage-providers) section).\\\nDefault value: `\"memory\"`\\\nEnv parameter: `STORAGE_PROVIDER`\n- **storageConnectionString**\\\nConnection string for storage provider.\\\nDefault value: `\"\"`\\\nEnv parameter: `STORAGE_CONNECTION_STRING`\n- **apiPort**\\\nAPI exposed by the notifier.\\\nDefault value: `4021`\\\nEnv parameter: `API_PORT`\n- **horizon**\\\nHorizon server URL.\\\nDefault value: `\"https://horizon.stellar.org\"`.\\\nEnv parameter: `HORIZON`\n- **reactionResponseTimeout**\\\nMaximum expected HTTP response timeout (in seconds). \nIf the reaction URL takes more time to respond, the request is aborted and\nnotification is marked as failed.\\\nDefault value: `10`.\\\nEnv parameter: `REACTION_RESPONSE_TIMEOUT`\n- **authorization**\\\nServer authorization mode.\\\n`disabled` mode turns off the authentication (recommended for local installations).\\\n`token` authentication expects `access_token` with user requests (see\n[API Authentication](#authentication)).\\\nDefault value: `\"disabled\"`.\\\nEnv parameter: `AUTHORIZATION`\n- **adminAuthenticationToken**\\\nAPI authentication token for admin user (for `\"authentication\"=\"token\"` mode). \nLeave empty to use a randomly generated token.\\\nDefault Value: `\"\"`.\\\nEnv parameter: `ADMIN_AUTHENTICATION_TOKEN`\n- **signatureSecret**\\\nSecret key used to sign the notifications. Do not forget to set your own secret. \nIt can be easily generated using [Stellar Laboratory](https://www.stellar.org/laboratory/#account-creator?network=test). \nDo not use the default value or a secret key from the funded account.\\\nDefault value: `\"\"`.\\\nEnv parameter: `SIGNATURE_SECRET`\n- **maxActiveSubscriptions**\\\nMaximum simultaneously tracked subscriptions.\\\nDefault value: `10000`.\\\nEnv parameter: `MAX_ACTIVE_SUBSCRIPTIONS`\n- **maxActiveSubscriptionsPerUser**\\\nMaximum simultaneously tracked subscriptions per user.\\\nDefault value: `100`.\\\nEnv parameter: `MAX_ACTIVE_SUBSCRIPTIONS_PER_USER`\n- **notificationConcurrency**\\\nMaximum concurrent notification threads (effectively, it equals the maximum\nparallel pending HTTP requests).\\\nDefault value: `100`.\\\nEnv parameter: `NOTIFICATION_CONCURRENCY`\n\n#### Storage providers\n\nNotifier can store notification queues and operational information in the\ndatabase or in memory. The latter option is suited only for testing or\ndeployments without guaranteed delivery.\n\nThere are two built-in storage providers: `mongodb` and `memory`.\nOther storage providers can be easily connected through the standard interface.\n\n#### Config example:\n\n```\n{\n  \"authorization\": \"disabled\",\n  \"storageProvider\": \"mongodb\",\n  \"storageConnectionString\": \"mongodb://127.0.0.1:27017/notifier\",\n  \"apiPort\": 4021,\n  \"horizon\": \"https://horizon.stellar.org\",\n  \"signatureSecret\": \"SDBT736EJIIRDC3RSN544NO6OSNMZAWAKRARLOMRP2XJAOGKTQLFFR3V\",\n  \"maxActiveSubscriptions\": 10000,\n  \"notificationConcurrency\": 100,\n  \"reactionResponseTimeout\": 10,\n  \"adminAuthenticationToken\": \"98c12910bf35c79a800e9ea893a93b078ea92fc7a26ca76c0cd2f6003464d781\"\n}\n```\n\n## API\n\n### Authentication\n\nWith `authorization` config parameter set to `disabled`, there is no need to\nbother about authentication. But it only works when the service is not exposed\nto public networks (i.e. behind the firewall).\n\nTo enable ed25519 authentication, set `authorization` parameter to `enabled`.\nIn this mode, any interaction with API requires an authorization\nheader `Authorization: ed25519 \u003cpublic_key\u003e.\u003csignature\u003e`, where `public_key` is\na ed25519 public key and `signature` is a cryptographic signature of urlencoded\nrequest params serialized in hex format. Please note, that all requests to \nAPI endpoints should contain `nonce` param and the value should be greater than\nin previous request.\n\n##### Example\n\n```\nconst {Keypair} = require('stellar-sdk')\n\n//encode path components\nfunction encodeUriParams(object) {\n    if (!object) return ''\n    return Object.keys(object)\n        .map(k =\u003e `${encodeURIComponent(k)}=${encodeURIComponent(object[k])}`)\n        .join('\u0026')\n}\n\n//GET request\n\nconst payload = encodeUriParams({ \n    nonce: Date.now(),\n    foo: 'foo'\n})\n\nconst keyPair = new KeyPair('private_key'),\n    signature = keyPair.sign(payload).toString('hex')\n\nconst authHeader = `ed25519 ${keyPair.publicKey()}.${signature}`,\n    requestUrl = `\u003cprotected_api_endpoint\u003e?${payload}`\n\n//set header and make request\n\n...\n\n//POST request\n\nconst body = {\n    nonce: Date.now(),\n    foo: 'foo'\n}\n\nconst keyPair = new KeyPair('private_key'),\n    signature = keyPair.sign(encodeUriParams(body)).toString('hex')\n\nconst authHeader = `ed25519 ${keyPair.publicKey()}.${signature}`\n\n//set header, body and make request\n```\n\n### Create subscription\n\n```\nPOST /api/subscription\n```\n\n**Parameters**:\n\n- **reaction_url** [*string*] (mandatory) - a full URL that should be requested\nby notification\n- **account** [*string*] (optional) - an account address to track\n- **memo** [*string*] (optional) - expected transaction memo\n- **account** [*string*] (optional) - an account address to track\n- **asset_code** [*string*] (optional) - asset code to track (specify XLM and no\nissuer to track operations involving XLM)\n- **asset_issuer** [*string*] (optional) - asset issuer to track\n- **operation_types** [*Array\\\u003cNumber\\\u003e*] (optional) - operation types to track\n\nNote: at least one operation filtering criteria should be specified.\n\nResponse example:\n\n```\n{\n  \"id\": \"5ae88ef89a9e5d4a589cf27d\",\n  \"user\": \"5ae87f6bc6073d3e6c9c7d1d\",\n  \"status\": 0,\n  \"delivery_failures\": 0,\n  \"sent\": 8,\n  \"reaction_url\": \"http://localhost:4022/test/reaction\",\n  \"operation_types\": [\n    0,\n    1\n  ],\n  \"created\": \"2018-05-01T15:59:52.475Z\",\n  \"updated\": \"2018-05-01T16:01:19.742Z\"\n}\n``` \n\nThe `id` value from response can be used to delete the subscription.\n\n### Remove subscription\n\n```\nDELETE /api/subscription/:subscription_id\n```\n\nThe endpoint returns 200 in case of successful unsubscription, and an error code\notherwise.\n\n**Parameters**:\n\n- **subscription_id** [*string*] (mandatory) - the subscription id to remove\n\n### Get all active user subscriptions\n\n```\nGET /api/subscription\n```\n\nResponse example:\n\n```\n[\n  {\n    \"id\": \"5ae88ef89a9e5d4a589cf27d\",\n    \"user\": \"5ae87f6bc6073d3e6c9c7d1d\",\n    \"status\": 0,\n    \"delivery_failures\": 0,\n    \"sent\": 8,\n    \"reaction_url\": \"http://localhost:4022/test/reaction\",\n    \"operation_types\": [\n      0,\n      1\n    ],\n    \"created\": \"2018-05-01T15:59:52.475Z\",\n    \"updated\": \"2018-05-01T16:01:19.742Z\"\n  },\n  {\n    \"id\": \"5ae88f54397cbf2474ef27e1\",\n    \"user\": \"5ae87f6bc6073d3e6c9c7d1d\",\n    \"status\": 0,\n    \"operation_types\": [],\n    \"delivery_failures\": 4,\n    \"sent\": 0,\n    \"reaction_url\": \"http://localhost:4022/test/reaction2\",\n    \"asset_type\": 0,\n    \"created\": \"2018-05-01T16:01:24.336Z\",\n    \"updated\": \"2018-05-01T16:02:01.036Z\"\n  }\n]\n```\n\n## Notifications Format\n\nNotifications are sent as JSON-encoded POST requests with the following format:\n\n```\n{\n  \"id\": \"5ae88ef89a9e5d4a589cf27d-757838947790641a6\",\n  \"subscription\": \"5ae88ef89a9e5d4a589cf29d\",\n  \"type\": \"operation\",\n  \"created\": \"2018-05-01T16:45:37.529Z\",\n  \"sent\": \"2018-05-01T16:45:37.991Z\",\n  \"operation\": {\n    \"id\": \"7578389477906432555\",\n    \"type_i\": 1,\n    \"type\": \"payment\",\n    \"destination\": \"GC3UA6FHLDD7IFG3MXA7JCNC2YPW62AKMKV5H2CEEBWCLUNJR3OFJSNV\",\n    \"asset\": {\n      \"asset_code\": \"ETH\",\n      \"asset_issuer\": \"GCNSGHUCG5VMGLT5RIYYZSO7VQULQKAJ62QA33DBC5PPBSO57LFWVV6P\",\n      \"asset_type\": \"1\"\n    },\n    \"amount\": \"0.0012\",\n    \"account\": \"GCUZSLQYXDXSOXC4DURSK3AJNAQEBDSYVGYE7BC7IXGTS32MJBW35QOU\"\n  },\n  \"transaction\": {\n    \"hash\": \"7580614b4703704496173f578092a0b6a56e5906d7ad5f83e529af14bab2cdd3\",\n    \"fee\": 600,\n    \"source\": \"GCUZSLQYXDXSOXC4DURSK3AJNAQEBDSYVGYE7BC7IXGTS32MJBW35QOU\",\n    \"paging_token\": \"757838947790643264\",\n    \"source_account_sequence\": \"7196037745321120376\",\n    \"created_at\": \"2018-05-01T16:45:37Z\",\n    \"memo\": { \n      \"type\": \"text\", \n      \"value\": \"105683157\"\n    }\n  }\n}\n```\n\nRequest headers:\n\n- `X-Request-ED25519-Signature` – the ED25519 signature for the notification body.\n- `X-Subscription` – corresponding subscription id.\n\n## Testing\n\nRun all tests (currently almost non existent) with \n\n```\nnpm run test\n```\n\n## Roadmap and Further Improvements\n\nThe following features will be added in the nearest future:\n\n- [x] The ability to use environment variables instead of the configuration file.\n- [x] Response validation for the flooding attacks prevention.\n- [ ] Implement other notification channels: email, messengers, etc.\n- [ ] Multi-account support and basic acquiring to turn the service into a SAAS\nplatform, so anyone could offer public SAAS notification services for some fee.\n- [ ] Comprehensive comments and test suites.\n- [ ] Bulletproof errors processing and graceful SIGTERM handling.\n\nHave a suggestion? Want to submit a bug or feature request? Visit the \n[issue tracker](https://github.com/stellar-expert/operations-notifier/issues).\n\n## Special Thanks and Acknowledgements\n\n- Many thanks to [@MikeFair](https://github.com/MikeFair) for his prominent ideas.\n- To [@sgehrman](https://github.com/sgehrman) for Docker setup and bug reports.\n- Kudos to [Stellar Developer Foundation](https://github.com/stellar) for the\nstate-of-the-art software and contemporary approach.\n- And, as always, thanks to awesome Stellar Community for the support.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstellar-expert%2Foperations-notifier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstellar-expert%2Foperations-notifier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstellar-expert%2Foperations-notifier/lists"}