diff --git a/.env.sample b/.env.sample
index 41151c4..235e273 100644
--- a/.env.sample
+++ b/.env.sample
@@ -5,5 +5,6 @@ CFG_VERSION=latest
CGW_VERSION=latest
TXS_VERSION=latest
UI_VERSION=latest
+EVENTS_VERSION=latest
RPC_NODE_URL=http://url.to.node
diff --git a/container_env_files/events.env b/container_env_files/events.env
new file mode 100644
index 0000000..1fd00c8
--- /dev/null
+++ b/container_env_files/events.env
@@ -0,0 +1,9 @@
+DATABASE_URL=psql://postgres:postgres@events-db:5432/postgres
+AMQP_URL=amqp://general-rabbitmq:5672
+AMQP_EXCHANGE=safe-transaction-service-events
+AMQP_QUEUE=safe-events-service
+ADMIN_EMAIL=admin@safe
+ADMIN_PASSWORD=password
+WEBHOOKS_CACHE_TTL=300000
+NODE_ENV=production
+URL_BASE_PATH=/events
\ No newline at end of file
diff --git a/container_env_files/txs.env b/container_env_files/txs.env
index 3830b32..47ce4cc 100644
--- a/container_env_files/txs.env
+++ b/container_env_files/txs.env
@@ -9,3 +9,6 @@ CELERY_BROKER_URL=amqp://guest:guest@txs-rabbitmq/
DJANGO_ALLOWED_HOSTS="*"
FORCE_SCRIPT_NAME=/txs/
CSRF_TRUSTED_ORIGINS="http://localhost:8000"
+EVENTS_QUEUE_URL=amqp://general-rabbitmq:5672
+EVENTS_QUEUE_ASYNC_CONNECTION=True
+EVENTS_QUEUE_EXCHANGE_NAME="safe-transaction-service-events"
diff --git a/docker-compose.yml b/docker-compose.yml
index aa0cd4c..5486ef9 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -32,6 +32,7 @@ services:
- txs-web
- cfg-web
- cgw-web
+ - events-web
txs-db:
image: postgres:14-alpine
@@ -49,6 +50,14 @@ services:
- ./data/cfg-db:/var/lib/postgresql/data
<<: *pghealthcheck
+ events-db:
+ image: postgres:14-alpine
+ environment:
+ POSTGRES_PASSWORD: postgres
+ volumes:
+ - ./data/events-db:/var/lib/postgresql/data
+ <<: *pghealthcheck
+
# Safe Transaction Service
txs-redis:
image: redis:alpine
@@ -152,3 +161,22 @@ services:
- nginx
ports:
- "${REVERSE_PROXY_UI_PORT}:8080"
+
+ general-rabbitmq:
+ image: rabbitmq:alpine
+ healthcheck:
+ test: rabbitmq-diagnostics -q ping
+ interval: 15s
+ timeout: 30s
+ retries: 3
+ start_period: 15s
+
+ events-web:
+ image: safeglobal/safe-events-service:${EVENTS_VERSION}
+ env_file:
+ - container_env_files/events.env
+ depends_on:
+ events-db:
+ condition: service_healthy
+ general-rabbitmq:
+ condition: service_healthy
\ No newline at end of file
diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf
index 8180228..51c0892 100644
--- a/docker/nginx/nginx.conf
+++ b/docker/nginx/nginx.conf
@@ -51,6 +51,15 @@ http {
keepalive 32;
}
+ upstream events_app_server {
+ ip_hash; # For load-balancing
+ server events-web:3000 fail_timeout=0;
+ #
+ # fail_timeout=0 means we always retry an upstream even if it failed
+ # to return a good HTTP response
+ keepalive 32;
+ }
+
server {
access_log off;
listen 8000 deferred;
@@ -120,6 +129,21 @@ http {
proxy_redirect off;
proxy_pass http://cgw_app_server/;
+ proxy_set_header X-Forwarded-Host $server_name;
+ proxy_set_header X-Real-IP $remote_addr;
+ add_header Front-End-Https on;
+ }
+
+ ## Events service mounting point
+ location /events/ {
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header Host $host;
+ # we don't want nginx trying to do something clever with
+ # redirects, we set the Host: header above already.
+ proxy_redirect off;
+ proxy_pass http://events_app_server/events/;
+
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
add_header Front-End-Https on;
diff --git a/docs/README.md b/docs/README.md
index 5e58eb7..019a661 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,10 +1,12 @@
# Safe Infrastructure
-![Safe Infrastructure Diagram](https://user-images.githubusercontent.com/6909403/231760296-afaa126c-db04-4f62-b996-c53b1d884247.png)
+**Safe infrastructure diagram**
+
- **Tx Service** is the core of the Safe. It indexes multisig transactions, module transactions, token transfers, collects signatures... There must be **1 Tx Service per Chain**, with different workers, PostgreSQL, Redis and RabbitMQ.
- **Config Service** holds configuration for every Chain (blockexplorer, tx service url, apps enabled, wallets enabled...). **1 instance of the Config Service supports multiple Chains**
- **Client Gateway** provides an API optimized for clients (web ui, android, ios...). **1 instance of the Client Gateway supports multiple Chains**
+- **Safe Events Service** handle Safe indexing events from Transaction Service and deliver as HTTP webhooks.
## Setup
@@ -16,6 +18,7 @@ CFG_VERSION=v2.60.0
CGW_VERSION=v0.4.1
TXS_VERSION=v4.6.1
UI_VERSION=v1.2.0
+EVENTS_VERSION=v0.5.0
```
You can change them to the version you are interested available in [docker-hub](https://hub.docker.com/u/safeglobal) but be aware that not all versions of our services are compatible with each other, so do so **at your own risk.**
diff --git a/docs/diagrams/safe-infrastructure-diagram.excalidraw b/docs/diagrams/safe-infrastructure-diagram.excalidraw
new file mode 100644
index 0000000..c5b4a6d
--- /dev/null
+++ b/docs/diagrams/safe-infrastructure-diagram.excalidraw
@@ -0,0 +1,2237 @@
+{
+ "type": "excalidraw",
+ "version": 2,
+ "source": "https://excalidraw.com",
+ "elements": [
+ {
+ "type": "text",
+ "version": 167,
+ "versionNonce": 270607626,
+ "isDeleted": false,
+ "id": "sD1x0jMsJnTUM_ySEbyaz",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 307.3938903808594,
+ "y": 192.40908813476562,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 362.20867919921875,
+ "height": 60,
+ "seed": 505134538,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423601046,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "Note: We use a nginx proxy in front of every \nservice as recommended for optimal traffic\nhandling",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "Note: We use a nginx proxy in front of every \nservice as recommended for optimal traffic\nhandling",
+ "lineHeight": 1.25,
+ "baseline": 53
+ },
+ {
+ "type": "rectangle",
+ "version": 564,
+ "versionNonce": 1723557846,
+ "isDeleted": false,
+ "id": "7v6RFTy4rXrm48mmvZNLr",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 823.0910339355469,
+ "y": 175.54540252685547,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 146.42425537109375,
+ "height": 63.212066650390625,
+ "seed": 615814486,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "S_sc7bcIyY3oORHx2V7oo"
+ },
+ {
+ "id": "0Bk2-EZ2FKtFYmGavgPZi",
+ "type": "arrow"
+ },
+ {
+ "id": "40gIggfspPB0WWSjYOLfN",
+ "type": "arrow"
+ },
+ {
+ "id": "6SvXZkZJp-HjLq8kekBfo",
+ "type": "arrow"
+ },
+ {
+ "id": "iJ4YvH_WGU98DeW0FJin7",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1696423525913,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 411,
+ "versionNonce": 1890336842,
+ "isDeleted": false,
+ "id": "S_sc7bcIyY3oORHx2V7oo",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 838.4630355834961,
+ "y": 187.15143585205078,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 115.68025207519531,
+ "height": 40,
+ "seed": 1489173974,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "\nClient gateway",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "7v6RFTy4rXrm48mmvZNLr",
+ "originalText": "\nClient gateway",
+ "lineHeight": 1.25,
+ "baseline": 33
+ },
+ {
+ "type": "rectangle",
+ "version": 223,
+ "versionNonce": 915515146,
+ "isDeleted": false,
+ "id": "9zm1OE6HjUAEzlGaCASwU",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 286.1213684082031,
+ "y": 357.30306243896484,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 146.42425537109375,
+ "height": 49.45454406738281,
+ "seed": 1832728394,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "GCMsc4PoVC2s_rgz29D5G"
+ }
+ ],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 86,
+ "versionNonce": 1913104022,
+ "isDeleted": false,
+ "id": "GCMsc4PoVC2s_rgz29D5G",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 313.62939453125,
+ "y": 372.03033447265625,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 91.408203125,
+ "height": 20,
+ "seed": 1352353942,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "PostgreSQL",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "9zm1OE6HjUAEzlGaCASwU",
+ "originalText": "PostgreSQL",
+ "lineHeight": 1.25,
+ "baseline": 13
+ },
+ {
+ "type": "rectangle",
+ "version": 602,
+ "versionNonce": 1352414666,
+ "isDeleted": false,
+ "id": "08XMKEKCbWyxhj3x9zOwQ",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1106.6061706542969,
+ "y": 170.75753784179688,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 146.42425537109375,
+ "height": 63.212066650390625,
+ "seed": 1579176278,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "JxA7FKVlPaskb7T8JRL-s"
+ },
+ {
+ "id": "0Bk2-EZ2FKtFYmGavgPZi",
+ "type": "arrow"
+ },
+ {
+ "id": "40gIggfspPB0WWSjYOLfN",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 456,
+ "versionNonce": 1052926934,
+ "isDeleted": false,
+ "id": "JxA7FKVlPaskb7T8JRL-s",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1159.3702545166016,
+ "y": 182.3635711669922,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 40.896087646484375,
+ "height": 40,
+ "seed": 1610069654,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "\nRedis",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "08XMKEKCbWyxhj3x9zOwQ",
+ "originalText": "\nRedis",
+ "lineHeight": 1.25,
+ "baseline": 33
+ },
+ {
+ "type": "rectangle",
+ "version": 738,
+ "versionNonce": 1340533898,
+ "isDeleted": false,
+ "id": "TQ9O-ISWmL-1u-e1vyW9N",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 555.9999694824219,
+ "y": 363.7878723144531,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 146.42425537109375,
+ "height": 54.48483276367187,
+ "seed": 642449238,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "HKT6vDDIrz-VVRxxnuXWx"
+ },
+ {
+ "id": "11U1jlQJKjSVQC6Tu_p-K",
+ "type": "arrow"
+ },
+ {
+ "id": "6SvXZkZJp-HjLq8kekBfo",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 535,
+ "versionNonce": 934508822,
+ "isDeleted": false,
+ "id": "HKT6vDDIrz-VVRxxnuXWx",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 587.276008605957,
+ "y": 371.03028869628906,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 83.87217712402344,
+ "height": 40,
+ "seed": 1788650646,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "\nTx Service",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "TQ9O-ISWmL-1u-e1vyW9N",
+ "originalText": "\nTx Service",
+ "lineHeight": 1.25,
+ "baseline": 33
+ },
+ {
+ "type": "rectangle",
+ "version": 883,
+ "versionNonce": 1781320522,
+ "isDeleted": false,
+ "id": "knU4ro8ph3J-2OrNTJFP8",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1217.3639221191406,
+ "y": 372.63633728027344,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 146.42425537109375,
+ "height": 54.48483276367187,
+ "seed": 590069962,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "V8BPB89LE5bDw2qLKYnoA"
+ }
+ ],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 767,
+ "versionNonce": 877651542,
+ "isDeleted": false,
+ "id": "V8BPB89LE5bDw2qLKYnoA",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1236.5999374389648,
+ "y": 389.8787536621094,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 107.95222473144531,
+ "height": 20,
+ "seed": 1582110602,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "Config Service",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "knU4ro8ph3J-2OrNTJFP8",
+ "originalText": "Config Service",
+ "lineHeight": 1.25,
+ "baseline": 13
+ },
+ {
+ "type": "rectangle",
+ "version": 903,
+ "versionNonce": 1296166346,
+ "isDeleted": false,
+ "id": "6iMOuWwT53Rvit3E6x02h",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1230.2428283691406,
+ "y": 491.45460510253906,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 146.42425537109375,
+ "height": 50.60604858398437,
+ "seed": 130128982,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "ttOeYk2CjrUJFUOWdVOF_"
+ },
+ {
+ "id": "4a5MeWqUIyB7QeObVLbvd",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1696423440255,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 725,
+ "versionNonce": 521512074,
+ "isDeleted": false,
+ "id": "ttOeYk2CjrUJFUOWdVOF_",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1257.7508544921875,
+ "y": 506.75762939453125,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 91.408203125,
+ "height": 20,
+ "seed": 2100797846,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423440255,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "PostgreSQL",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "6iMOuWwT53Rvit3E6x02h",
+ "originalText": "PostgreSQL",
+ "lineHeight": 1.25,
+ "baseline": 13
+ },
+ {
+ "type": "rectangle",
+ "version": 796,
+ "versionNonce": 95813834,
+ "isDeleted": false,
+ "id": "W43uI9ww70hVBUpr7zwZT",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 406.0909118652344,
+ "y": 515.7272796630859,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 146.42425537109375,
+ "height": 54.48483276367187,
+ "seed": 1375235926,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "yuNZi4c5-RbieitK4LlRZ"
+ },
+ {
+ "id": "Ht-e0INEKWC-XXDrSdB89",
+ "type": "arrow"
+ },
+ {
+ "id": "3-2zDzy2LvOlbvohvBhrR",
+ "type": "arrow"
+ },
+ {
+ "id": "6pZNdKEPPG6OIx4oZxpwr",
+ "type": "arrow"
+ },
+ {
+ "id": "zUF3a5BFye6FOZleuXDVy",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 614,
+ "versionNonce": 1497286870,
+ "isDeleted": false,
+ "id": "yuNZi4c5-RbieitK4LlRZ",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 427.00694274902344,
+ "y": 522.9696960449219,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 104.59219360351562,
+ "height": 40,
+ "seed": 521933974,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "Async Celery \nWorkers",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "W43uI9ww70hVBUpr7zwZT",
+ "originalText": "Async Celery \nWorkers",
+ "lineHeight": 1.25,
+ "baseline": 33
+ },
+ {
+ "type": "rectangle",
+ "version": 699,
+ "versionNonce": 823179082,
+ "isDeleted": false,
+ "id": "0qkTAhSvhnwIXJIUecPXw",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 643.0907287597656,
+ "y": 514.2727508544922,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 146.42425537109375,
+ "height": 63.212066650390625,
+ "seed": 1989939478,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "BjRy_TZPqh2hvJvrAQR2d"
+ },
+ {
+ "id": "JGWNaYJ_6-0pGi7GB5Ysb",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1696423810393,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 484,
+ "versionNonce": 21970442,
+ "isDeleted": false,
+ "id": "BjRy_TZPqh2hvJvrAQR2d",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 695.8548126220703,
+ "y": 525.8787841796875,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 40.896087646484375,
+ "height": 40,
+ "seed": 979730006,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423810393,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "\nRedis",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "0qkTAhSvhnwIXJIUecPXw",
+ "originalText": "\nRedis",
+ "lineHeight": 1.25,
+ "baseline": 33
+ },
+ {
+ "type": "rectangle",
+ "version": 751,
+ "versionNonce": 898618954,
+ "isDeleted": false,
+ "id": "AtyFNzoAKa0LLjGZrLeNh",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 656.4848327636719,
+ "y": 664.2728118896484,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 146.42425537109375,
+ "height": 63.212066650390625,
+ "seed": 481742410,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "K47rtJZT17RfSrv_YAzgN"
+ }
+ ],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 552,
+ "versionNonce": 213322582,
+ "isDeleted": false,
+ "id": "K47rtJZT17RfSrv_YAzgN",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 674.2088241577148,
+ "y": 685.8788452148438,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 110.97627258300781,
+ "height": 20,
+ "seed": 1578792202,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "Txs-RabbitMQ",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "AtyFNzoAKa0LLjGZrLeNh",
+ "originalText": "Txs-RabbitMQ",
+ "lineHeight": 1.25,
+ "baseline": 13
+ },
+ {
+ "type": "rectangle",
+ "version": 837,
+ "versionNonce": 110263562,
+ "isDeleted": false,
+ "id": "tOnCydTTzKGQHIJ2U2m-6",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 405.3030090332031,
+ "y": 664.0908050537109,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 146.42425537109375,
+ "height": 63.212066650390625,
+ "seed": 1581851466,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "zXXk_aqXLKRnbmzDbTxeY"
+ },
+ {
+ "id": "Ht-e0INEKWC-XXDrSdB89",
+ "type": "arrow"
+ },
+ {
+ "id": "o_03HL0fJgM4UiLYOxvfk",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 648,
+ "versionNonce": 1067921558,
+ "isDeleted": false,
+ "id": "zXXk_aqXLKRnbmzDbTxeY",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 415.0910110473633,
+ "y": 685.6968383789062,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 126.84825134277344,
+ "height": 20,
+ "seed": 1150953994,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "Celery Scheduler",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "tOnCydTTzKGQHIJ2U2m-6",
+ "originalText": "Celery Scheduler",
+ "lineHeight": 1.25,
+ "baseline": 13
+ },
+ {
+ "type": "arrow",
+ "version": 269,
+ "versionNonce": 1444039626,
+ "isDeleted": false,
+ "id": "Ht-e0INEKWC-XXDrSdB89",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 476.12139892578125,
+ "y": 661.0302734375,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 0,
+ "height": 88.242431640625,
+ "seed": 887133770,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "8VTkjwY8qLJfIl5aeSq2A"
+ }
+ ],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "tOnCydTTzKGQHIJ2U2m-6",
+ "focus": -0.03269591895006909,
+ "gap": 3.0605316162109375
+ },
+ "endBinding": {
+ "elementId": "W43uI9ww70hVBUpr7zwZT",
+ "focus": 0.04345783582011784,
+ "gap": 2.5757293701171875
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -88.242431640625
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 79,
+ "versionNonce": 65056214,
+ "isDeleted": false,
+ "id": "8VTkjwY8qLJfIl5aeSq2A",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 420.0732727050781,
+ "y": 606.9090576171875,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 112.09625244140625,
+ "height": 20,
+ "seed": 1251988246,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "Periodic tasks",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "Ht-e0INEKWC-XXDrSdB89",
+ "originalText": "Periodic tasks",
+ "lineHeight": 1.25,
+ "baseline": 13
+ },
+ {
+ "type": "arrow",
+ "version": 266,
+ "versionNonce": 376996630,
+ "isDeleted": false,
+ "id": "0Bk2-EZ2FKtFYmGavgPZi",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 969.6970825195312,
+ "y": 187.81814575195312,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 134.78790283203125,
+ "height": 0.969696044921875,
+ "seed": 1915409354,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "7v6RFTy4rXrm48mmvZNLr",
+ "focus": -0.5852372890979475,
+ "gap": 1
+ },
+ "endBinding": {
+ "elementId": "08XMKEKCbWyxhj3x9zOwQ",
+ "focus": 0.499711129047237,
+ "gap": 2.121185302734375
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 134.78790283203125,
+ -0.969696044921875
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 272,
+ "versionNonce": 227893578,
+ "isDeleted": false,
+ "id": "40gIggfspPB0WWSjYOLfN",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1104.4849853515625,
+ "y": 208.18177795410156,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 134.78790283203125,
+ "height": 0.969696044921875,
+ "seed": 1665840394,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "08XMKEKCbWyxhj3x9zOwQ",
+ "focus": -0.16420141377070172,
+ "gap": 2.121185302734375
+ },
+ "endBinding": {
+ "elementId": "7v6RFTy4rXrm48mmvZNLr",
+ "focus": 0.07867525371999128,
+ "gap": 1
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -134.78790283203125,
+ 0.969696044921875
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 149,
+ "versionNonce": 1239658582,
+ "isDeleted": false,
+ "id": "w5GguzQUKftMWrI5gLjhY",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 964.8485717773438,
+ "y": 235.33328247070312,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 254.06060791015625,
+ "height": 138.666748046875,
+ "seed": 847555286,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "OAmhf3QUTFjxxJDzWGA1z"
+ }
+ ],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 254.06060791015625,
+ 138.666748046875
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 110,
+ "versionNonce": 2075043850,
+ "isDeleted": false,
+ "id": "OAmhf3QUTFjxxJDzWGA1z",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1006.9818572998047,
+ "y": 283.6969451904297,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 54.400115966796875,
+ "height": 40,
+ "seed": 611410198,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "queries\n",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "w5GguzQUKftMWrI5gLjhY",
+ "originalText": "queries\n",
+ "lineHeight": 1.25,
+ "baseline": 33
+ },
+ {
+ "type": "arrow",
+ "version": 214,
+ "versionNonce": 1388610378,
+ "isDeleted": false,
+ "id": "4a5MeWqUIyB7QeObVLbvd",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1296.4853515625,
+ "y": 425.3939208984375,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 37.97785251555638,
+ "height": 63.030303955078125,
+ "seed": 1153088854,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1696423440255,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "6iMOuWwT53Rvit3E6x02h",
+ "focus": 0.5435352784610166,
+ "gap": 3.0303802490234375
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 37.97785251555638,
+ 63.030303955078125
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 177,
+ "versionNonce": 1282479818,
+ "isDeleted": false,
+ "id": "6SvXZkZJp-HjLq8kekBfo",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 822.0910339355469,
+ "y": 206.6818920910676,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 137.28051316012807,
+ "height": 152.77266723510428,
+ "seed": 2030649162,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "6nQ9USXgRog1wMZ_c4zu7"
+ }
+ ],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "7v6RFTy4rXrm48mmvZNLr",
+ "focus": 0.7345053882423703,
+ "gap": 1
+ },
+ "endBinding": {
+ "elementId": "TQ9O-ISWmL-1u-e1vyW9N",
+ "focus": 0.2786787615822899,
+ "gap": 4.33331298828125
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -137.28051316012807,
+ 152.77266723510428
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 9,
+ "versionNonce": 1072173782,
+ "isDeleted": false,
+ "id": "6nQ9USXgRog1wMZ_c4zu7",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 703.9515228271484,
+ "y": 279.15152740478516,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 54.400115966796875,
+ "height": 20,
+ "seed": 594710154,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "queries",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "6SvXZkZJp-HjLq8kekBfo",
+ "originalText": "queries",
+ "lineHeight": 1.25,
+ "baseline": 13
+ },
+ {
+ "type": "arrow",
+ "version": 195,
+ "versionNonce": 544714122,
+ "isDeleted": false,
+ "id": "11U1jlQJKjSVQC6Tu_p-K",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 553.6970825195312,
+ "y": 387.5757751464844,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 123.15155029296875,
+ "height": 5.818206787109375,
+ "seed": 2126903498,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "TQ9O-ISWmL-1u-e1vyW9N",
+ "focus": -0.003685164384205496,
+ "gap": 2.302886962890625
+ },
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -123.15155029296875,
+ -5.818206787109375
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 188,
+ "versionNonce": 105596950,
+ "isDeleted": false,
+ "id": "3-2zDzy2LvOlbvohvBhrR",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 414.0606994628906,
+ "y": 514.6060485839844,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 46.54541015625,
+ "height": 111.51516723632812,
+ "seed": 1011566358,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "W43uI9ww70hVBUpr7zwZT",
+ "focus": -0.6313762785692306,
+ "gap": 1.1212310791015625
+ },
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -46.54541015625,
+ -111.51516723632812
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 206,
+ "versionNonce": 1291676746,
+ "isDeleted": false,
+ "id": "o_03HL0fJgM4UiLYOxvfk",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 404.36376953125,
+ "y": 677.51513671875,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 78.54550170898438,
+ "height": 274.42425537109375,
+ "seed": 1650150346,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "tOnCydTTzKGQHIJ2U2m-6",
+ "focus": -0.8381810127778695,
+ "gap": 1
+ },
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -78.54550170898438,
+ -274.42425537109375
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 96,
+ "versionNonce": 487970134,
+ "isDeleted": false,
+ "id": "qJx--rtwewLauZW4wlXBp",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 549.8182983398438,
+ "y": 693.0302734375,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 107.6363525390625,
+ "height": 1.93939208984375,
+ "seed": 1929484694,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 107.6363525390625,
+ 1.93939208984375
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 141,
+ "versionNonce": 1205687050,
+ "isDeleted": false,
+ "id": "Twrib3ErHABbt4akotL2Z",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 550.7879638671875,
+ "y": 564.0606689453125,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 113.45465087890625,
+ "height": 103.75750732421875,
+ "seed": 1703889610,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": "arrow",
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 113.45465087890625,
+ 103.75750732421875
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 221,
+ "versionNonce": 765246102,
+ "isDeleted": false,
+ "id": "6pZNdKEPPG6OIx4oZxpwr",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 552.7273559570312,
+ "y": 539.8181762695312,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 94.06060791015625,
+ "height": 0.96966552734375,
+ "seed": 254885066,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "W43uI9ww70hVBUpr7zwZT",
+ "focus": -0.13960156947451183,
+ "gap": 1
+ },
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 94.06060791015625,
+ 0.96966552734375
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 194,
+ "versionNonce": 328360394,
+ "isDeleted": false,
+ "id": "zUF3a5BFye6FOZleuXDVy",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 583.7576904296875,
+ "y": 415.6969909667969,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 106.66668701171875,
+ "height": 96.96966552734375,
+ "seed": 287811094,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "UwvswjW3wPxeA1SQb5mUW"
+ }
+ ],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "W43uI9ww70hVBUpr7zwZT",
+ "focus": -0.3445029057597297,
+ "gap": 3.0606231689453125
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -106.66668701171875,
+ 96.96966552734375
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 80,
+ "versionNonce": 1855256534,
+ "isDeleted": false,
+ "id": "UwvswjW3wPxeA1SQb5mUW",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 462.8241958618164,
+ "y": 454.18182373046875,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 135.20030212402344,
+ "height": 20,
+ "seed": 1941557718,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "On demand tasks",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "zUF3a5BFye6FOZleuXDVy",
+ "originalText": "On demand tasks",
+ "lineHeight": 1.25,
+ "baseline": 13
+ },
+ {
+ "type": "arrow",
+ "version": 178,
+ "versionNonce": 1032776906,
+ "isDeleted": false,
+ "id": "JGWNaYJ_6-0pGi7GB5Ysb",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 604.1213989257812,
+ "y": 416.66668701171875,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 68.66974528463584,
+ "height": 96.60606384277344,
+ "seed": 1024319178,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1696423810393,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "0qkTAhSvhnwIXJIUecPXw",
+ "focus": -0.21253089622469093,
+ "gap": 1
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 68.66974528463584,
+ 96.60606384277344
+ ]
+ ]
+ },
+ {
+ "type": "rectangle",
+ "version": 1265,
+ "versionNonce": 843097226,
+ "isDeleted": false,
+ "id": "XfTfaPgaWfCx7Mgex6b-M",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 786.2728576660156,
+ "y": 438.4545135498047,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 146.42425537109375,
+ "height": 56.4241943359375,
+ "seed": 738657546,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "tHC-jjr9rIHIph1NrZY__"
+ },
+ {
+ "id": "ri310Z-QRPktp56G38nZF",
+ "type": "arrow"
+ },
+ {
+ "id": "kt8jgthqY5PUYXYDTuJN0",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1696423485488,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 1165,
+ "versionNonce": 162403082,
+ "isDeleted": false,
+ "id": "tHC-jjr9rIHIph1NrZY__",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 822.5568923950195,
+ "y": 446.66661071777344,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 73.85618591308594,
+ "height": 40,
+ "seed": 1807078346,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423803491,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "General-\nRabbitMQ",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "XfTfaPgaWfCx7Mgex6b-M",
+ "originalText": "General-RabbitMQ",
+ "lineHeight": 1.25,
+ "baseline": 33
+ },
+ {
+ "type": "arrow",
+ "version": 422,
+ "versionNonce": 1460963850,
+ "isDeleted": false,
+ "id": "ri310Z-QRPktp56G38nZF",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 702.0606079101562,
+ "y": 388.5455017089844,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 81.454833984375,
+ "height": 73.99757410035352,
+ "seed": 1782296342,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "ofvo_fRiK9CyM7b0iOcDE"
+ }
+ ],
+ "updated": 1696423485488,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "XfTfaPgaWfCx7Mgex6b-M",
+ "focus": -0.6850701142515723,
+ "gap": 2.757415771484375
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 81.454833984375,
+ 73.99757410035352
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 8,
+ "versionNonce": 1983261898,
+ "isDeleted": false,
+ "id": "ofvo_fRiK9CyM7b0iOcDE",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 714.8276901245117,
+ "y": 380.48487854003906,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 51.07209777832031,
+ "height": 20,
+ "seed": 1359360598,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423433143,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "events",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "ri310Z-QRPktp56G38nZF",
+ "originalText": "events",
+ "lineHeight": 1.25,
+ "baseline": 13
+ },
+ {
+ "type": "rectangle",
+ "version": 1447,
+ "versionNonce": 1644988694,
+ "isDeleted": false,
+ "id": "a3CeWizAo_BNtQEzY-u7X",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1038.5149230957031,
+ "y": 439.2424011230469,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 146.42425537109375,
+ "height": 56.4241943359375,
+ "seed": 553956554,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "FuYndGorTaLOXtUKhg9kT"
+ },
+ {
+ "id": "kt8jgthqY5PUYXYDTuJN0",
+ "type": "arrow"
+ },
+ {
+ "id": "iJ4YvH_WGU98DeW0FJin7",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1696423560974,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 1355,
+ "versionNonce": 1359410774,
+ "isDeleted": false,
+ "id": "FuYndGorTaLOXtUKhg9kT",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1054.6869354248047,
+ "y": 457.4544982910156,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 114.08023071289062,
+ "height": 20,
+ "seed": 484936586,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423560974,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "Events service",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "a3CeWizAo_BNtQEzY-u7X",
+ "originalText": "Events service",
+ "lineHeight": 1.25,
+ "baseline": 13
+ },
+ {
+ "type": "arrow",
+ "version": 344,
+ "versionNonce": 1601296598,
+ "isDeleted": false,
+ "id": "kt8jgthqY5PUYXYDTuJN0",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 933.6971130371094,
+ "y": 471.0160248464241,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 102.90908813476562,
+ "height": 3.2146345491082116,
+ "seed": 1237018262,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1696423560975,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "XfTfaPgaWfCx7Mgex6b-M",
+ "focus": 0.21923448961614644,
+ "gap": 1
+ },
+ "endBinding": {
+ "elementId": "a3CeWizAo_BNtQEzY-u7X",
+ "focus": 0.06556607334071446,
+ "gap": 1.908721923828125
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": "arrow",
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 102.90908813476562,
+ -3.2146345491082116
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 115,
+ "versionNonce": 1298537302,
+ "isDeleted": false,
+ "id": "iJ4YvH_WGU98DeW0FJin7",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1085.9305310966981,
+ "y": 437.0303039550781,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 161.24462013436766,
+ "height": 197.27283477783203,
+ "seed": 1157092298,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "l9t6kp9MsC2pE-d-xZDeF"
+ }
+ ],
+ "updated": 1696423560975,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "a3CeWizAo_BNtQEzY-u7X",
+ "focus": -0.009455548841979862,
+ "gap": 2.21209716796875
+ },
+ "endBinding": {
+ "elementId": "7v6RFTy4rXrm48mmvZNLr",
+ "focus": -0.017482818760708573,
+ "gap": 1
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -161.24462013436766,
+ -197.27283477783203
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 9,
+ "versionNonce": 1029690902,
+ "isDeleted": false,
+ "id": "l9t6kp9MsC2pE-d-xZDeF",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 970.2380676269531,
+ "y": 328.1212158203125,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 68.73614501953125,
+ "height": 20,
+ "seed": 1731711690,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423533544,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "webhooks",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "iJ4YvH_WGU98DeW0FJin7",
+ "originalText": "webhooks",
+ "lineHeight": 1.25,
+ "baseline": 13
+ },
+ {
+ "type": "rectangle",
+ "version": 42,
+ "versionNonce": 1442333258,
+ "isDeleted": false,
+ "id": "-YHFQqWI__CqLs2A5xqgK",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1032.727294921875,
+ "y": 592.1818237304688,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 174.54541015625,
+ "height": 63.0303955078125,
+ "seed": 1906953622,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 3
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "18HVC88zmruCDakIZsVkc"
+ }
+ ],
+ "updated": 1696423543115,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 47,
+ "versionNonce": 1463326282,
+ "isDeleted": false,
+ "id": "18HVC88zmruCDakIZsVkc",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1064.1598663330078,
+ "y": 603.697021484375,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 111.68026733398438,
+ "height": 40,
+ "seed": 200938006,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423731625,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "Third parties \nsubscribers",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "-YHFQqWI__CqLs2A5xqgK",
+ "originalText": "Third parties subscribers",
+ "lineHeight": 1.25,
+ "baseline": 33
+ },
+ {
+ "type": "arrow",
+ "version": 114,
+ "versionNonce": 725531722,
+ "isDeleted": false,
+ "id": "NDv9EopeSf1bR_0ARX_q-",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1109.3333740234375,
+ "y": 490.3636474609375,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 2.9090576171875,
+ "height": 102.7879638671875,
+ "seed": 551435210,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "a1A12toJpDUYuUWcEseZW"
+ }
+ ],
+ "updated": 1696423587380,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0.9697265625,
+ 51.39398193359375
+ ],
+ [
+ 2.9090576171875,
+ 102.7879638671875
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 11,
+ "versionNonce": 793756374,
+ "isDeleted": false,
+ "id": "a1A12toJpDUYuUWcEseZW",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1075.9350280761719,
+ "y": 531.7576293945312,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 68.73614501953125,
+ "height": 20,
+ "seed": 814365834,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423586569,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "webhooks",
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "NDv9EopeSf1bR_0ARX_q-",
+ "originalText": "webhooks",
+ "lineHeight": 1.25,
+ "baseline": 13
+ },
+ {
+ "type": "text",
+ "version": 430,
+ "versionNonce": 388789270,
+ "isDeleted": false,
+ "id": "k7IQetze0tTDsa9h0ZaCO",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 731.5321350097656,
+ "y": 364.3909316416756,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 276.01654052734375,
+ "height": 40,
+ "seed": 1311697546,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1696423689129,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 1,
+ "text": "Note: There must be 1 Tx Service \nfor every chain",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "Note: There must be 1 Tx Service \nfor every chain",
+ "lineHeight": 1.25,
+ "baseline": 33
+ }
+ ],
+ "appState": {
+ "gridSize": null,
+ "viewBackgroundColor": "#ffffff"
+ },
+ "files": {}
+}
\ No newline at end of file
diff --git a/docs/diagrams/safe-infrastructure-diagram.png b/docs/diagrams/safe-infrastructure-diagram.png
new file mode 100644
index 0000000..17f976d
Binary files /dev/null and b/docs/diagrams/safe-infrastructure-diagram.png differ
diff --git a/docs/running_locally.md b/docs/running_locally.md
index 0c89553..258df0d 100644
--- a/docs/running_locally.md
+++ b/docs/running_locally.md
@@ -68,7 +68,7 @@ Check this [section](chain_info.md) for a more complete guide on the fields for
## Step 4: Add your webhooks
-Our services invalidate the caches of the client gateway using webhooks. Both the Config and Transaction service need to be configured. For the Config service, unless you've changed the values in `cgw.env` and `cfg.env` then you don't need to do anything, otherwise:
+Our services invalidate the caches of the client gateway using webhooks. Both the Config and Events service need to be configured. For the Config service, unless you've changed the values in `cgw.env` and `cfg.env` then you don't need to do anything, otherwise:
```bash
@@ -83,14 +83,17 @@ AUTH_TOKEN=some_random_token
`AUTH_TOKEN` and `CGW_FLUSH_TOKEN` must be the same.
-For the Transactions service, follow these steps:
+For the Events service, follow these steps:
-- Access the admin panel at `http://localhost:8000/txs/admin`
-- click the `Add` link for `Web hooks`
-- Ignore the `Address` field
-- Set the `Url` field to `http://nginx:8000/cgw/v1/chains/{chainId}/hooks/events` and replace `{chainId}` with the corresponding chainId
+- Access the admin panel at `http://localhost:8000/events/admin`
+- Default user and password is defined in `container_env_files/events.env`
+- Click on `Webhook` at the left column and then click on `Create new`
+- Set the `Url` field to `http://nginx:8000/cgw/v1/hooks/events`
+- Set description `CGW`
+- Enable `Is Active` field
- Set the `Authorization` field to `Basic `, where `` corresponds to the value of `AUTH_TOKEN` in the `container_env_files/cgw.env` file of this repository
-- Optionally: Add the Safe Master Copy of your network at `http://localhost:8000/txs/admin/history/safemastercopy`, where `version` corresponds to the version of your deployed Safe Master Copy. Check L2 if it concerns the Safe L2 version. This is required for chains that were not added to [safe-eth-py](https://github.com/safe-global/safe-eth-py/blob/master/gnosis/safe/addresses.py)
+- Leave chains field blank
+- Enable every webhook option and click `Save`
# Safe Web App