diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000000000000000000000000000000000000..7e38aab1ee86d11d2d4eafb02b3d2f71b6ee2e86
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,4 @@
+# === POSTGRES / HASURA ===
+DB_PASSWORD=my_db_password
+HASURA_GRAPHQL_ADMIN_SECRET=my_hasura_password
+HASURA_LISTEN_PORT=8765
diff --git a/.gitignore b/.gitignore
index a547bf36d8d11a4f89c59c144f24795749086dd1..118821d6b2af69d91b87eb11664624e315448843 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,23 +2,10 @@
 logs
 *.log
 npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
 pnpm-debug.log*
-lerna-debug.log*
 
 node_modules
-dist
-dist-ssr
 *.local
 
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
+# Env
+.env
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000000000000000000000000000000000000..f5e72298e205957eda80c893d34cf3379005d18d
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,17 @@
+{
+  // Utilisez IntelliSense pour en savoir plus sur les attributs possibles.
+  // Pointez pour afficher la description des attributs existants.
+  // Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "name": "C+ import",
+      "type": "node",
+      "request": "launch",
+      "cwd": "${workspaceRoot}",
+      "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/tsx",
+      "program": "./src/scripts/cesium-plus-import.ts",
+      "console": "integratedTerminal"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0bce8ce7df41d44dacec8c66ab4e277c586f3067
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,36 @@
+version: "3.6"
+services:
+  postgres:
+    image: postgres:16
+    restart: always
+    volumes:
+      - db_data:/var/lib/postgresql/data
+    environment:
+      POSTGRES_PASSWORD: ${DB_PASSWORD}
+    healthcheck:
+      test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
+      interval: 2s
+      timeout: 2s
+      retries: 5
+
+  hasura:
+    image: hasura/graphql-engine:v2.38.1.cli-migrations-v3
+    depends_on:
+      postgres:
+        condition: service_healthy
+    restart: always
+    ports:
+      - "${HASURA_LISTEN_PORT}:8080"
+    environment:
+      HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:${DB_PASSWORD}@postgres:5432/postgres
+      HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
+      HASURA_GRAPHQL_DEV_MODE: "true"
+      HASURA_GRAPHQL_UNAUTHORIZED_ROLE: public
+      HASURA_GRAPHQL_ENABLE_TELEMETRY: "false"
+      HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_GRAPHQL_ADMIN_SECRET}
+    volumes: # for local developement, you want to record the database migrations in git
+      - ./hasura/migrations:/hasura-migrations
+      - ./hasura/metadata:/hasura-metadata
+
+volumes:
+  db_data:
diff --git a/hasura/metadata/actions.graphql b/hasura/metadata/actions.graphql
new file mode 100644
index 0000000000000000000000000000000000000000..2d49d28b67547d8c9f5c15736fc777d1164fe8f8
--- /dev/null
+++ b/hasura/metadata/actions.graphql
@@ -0,0 +1,71 @@
+type Mutation {
+  addTransaction(
+    id: String!
+    address: String!
+    hash: String!
+    signature: String!
+    comment: String!
+  ): AddTransactionResponse
+}
+
+type Mutation {
+  deleteProfile(
+    address: String!
+    hash: String!
+    signature: String!
+  ): DeleteProfileResponse
+}
+
+type Mutation {
+  migrateProfile(
+    addressOld: String!
+    addressNew: String!
+    hash: String!
+    signature: String!
+  ): MigrateProfileResponse
+}
+
+type Mutation {
+  updateProfile(
+    address: String!
+    hash: String!
+    signature: String!
+    avatarBase64: String
+    title: String
+    description: String
+    city: String
+    socials: [SocialInput!]
+    geoloc: GeolocInput
+  ): UpdateProfileResponse
+}
+
+input GeolocInput {
+  latitude: Float!
+  longitude: Float!
+}
+
+input SocialInput {
+  url: String!
+  type: String
+}
+
+type UpdateProfileResponse {
+  success: Boolean!
+  message: String!
+}
+
+type DeleteProfileResponse {
+  success: Boolean!
+  message: String!
+}
+
+type MigrateProfileResponse {
+  success: Boolean!
+  message: String!
+}
+
+type AddTransactionResponse {
+  success: Boolean!
+  message: String!
+}
+
diff --git a/hasura/metadata/actions.yaml b/hasura/metadata/actions.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b03cfce6a65fb6beb9c2f1615410f6efe8b35c51
--- /dev/null
+++ b/hasura/metadata/actions.yaml
@@ -0,0 +1,41 @@
+actions:
+  - name: addTransaction
+    definition:
+      kind: synchronous
+      handler: http://host.docker.internal:3000/add-transaction
+    permissions:
+      - role: public
+    comment: addTransaction
+  - name: deleteProfile
+    definition:
+      kind: synchronous
+      handler: http://host.docker.internal:3000/delete-profile-data
+    permissions:
+      - role: public
+    comment: deleteProfile
+  - name: migrateProfile
+    definition:
+      kind: synchronous
+      handler: http://host.docker.internal:3000/migrate-profile-data
+    permissions:
+      - role: public
+    comment: migrateProfile
+  - name: updateProfile
+    definition:
+      kind: synchronous
+      handler: http://host.docker.internal:3000/update-profile-data
+      timeout: 15
+    permissions:
+      - role: public
+    comment: updateProfile
+custom_types:
+  enums: []
+  input_objects:
+    - name: GeolocInput
+    - name: SocialInput
+  objects:
+    - name: UpdateProfileResponse
+    - name: DeleteProfileResponse
+    - name: MigrateProfileResponse
+    - name: AddTransactionResponse
+  scalars: []
diff --git a/hasura/metadata/allow_list.yaml b/hasura/metadata/allow_list.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fe51488c7066f6687ef680d6bfaa4f7768ef205c
--- /dev/null
+++ b/hasura/metadata/allow_list.yaml
@@ -0,0 +1 @@
+[]
diff --git a/hasura/metadata/api_limits.yaml b/hasura/metadata/api_limits.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93
--- /dev/null
+++ b/hasura/metadata/api_limits.yaml
@@ -0,0 +1 @@
+{}
diff --git a/hasura/metadata/backend_configs.yaml b/hasura/metadata/backend_configs.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93
--- /dev/null
+++ b/hasura/metadata/backend_configs.yaml
@@ -0,0 +1 @@
+{}
diff --git a/hasura/metadata/cron_triggers.yaml b/hasura/metadata/cron_triggers.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fe51488c7066f6687ef680d6bfaa4f7768ef205c
--- /dev/null
+++ b/hasura/metadata/cron_triggers.yaml
@@ -0,0 +1 @@
+[]
diff --git a/hasura/metadata/databases/databases.yaml b/hasura/metadata/databases/databases.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..65a11b202ed88526ac3cff9018de41a763814fd9
--- /dev/null
+++ b/hasura/metadata/databases/databases.yaml
@@ -0,0 +1,14 @@
+- name: default
+  kind: postgres
+  configuration:
+    connection_info:
+      database_url:
+        from_env: HASURA_GRAPHQL_DATABASE_URL
+      isolation_level: read-committed
+      pool_settings:
+        connection_lifetime: 600
+        idle_timeout: 180
+        max_connections: 50
+        retries: 1
+      use_prepared_statements: true
+  tables: "!include default/tables/tables.yaml"
diff --git a/hasura/metadata/databases/default/tables/public_profiles.yaml b/hasura/metadata/databases/default/tables/public_profiles.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f94138f5d872f65ba8ad2ae6f088bbcfbc76d7bd
--- /dev/null
+++ b/hasura/metadata/databases/default/tables/public_profiles.yaml
@@ -0,0 +1,25 @@
+table:
+  name: profiles
+  schema: public
+computed_fields:
+  - name: avatar64
+    definition:
+      function:
+        name: bytea_to_base64
+        schema: public
+    comment: convert avatar from bytea to base64
+select_permissions:
+  - role: public
+    permission:
+      columns:
+        - avatar
+        - address
+        - geoloc
+        - description
+        - created_at
+        - updated_at
+      computed_fields:
+        - avatar64
+      filter: {}
+      limit: 500
+    comment: ""
diff --git a/hasura/metadata/databases/default/tables/tables.yaml b/hasura/metadata/databases/default/tables/tables.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6dc41508ffaf12842ee7663763870f4b4529fc01
--- /dev/null
+++ b/hasura/metadata/databases/default/tables/tables.yaml
@@ -0,0 +1 @@
+- "!include public_profiles.yaml"
diff --git a/hasura/metadata/graphql_schema_introspection.yaml b/hasura/metadata/graphql_schema_introspection.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..61a4dcac291837aacfc6d5e3de7dcc73da320ea3
--- /dev/null
+++ b/hasura/metadata/graphql_schema_introspection.yaml
@@ -0,0 +1 @@
+disabled_for_roles: []
diff --git a/hasura/metadata/inherited_roles.yaml b/hasura/metadata/inherited_roles.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fe51488c7066f6687ef680d6bfaa4f7768ef205c
--- /dev/null
+++ b/hasura/metadata/inherited_roles.yaml
@@ -0,0 +1 @@
+[]
diff --git a/hasura/metadata/metrics_config.yaml b/hasura/metadata/metrics_config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93
--- /dev/null
+++ b/hasura/metadata/metrics_config.yaml
@@ -0,0 +1 @@
+{}
diff --git a/hasura/metadata/network.yaml b/hasura/metadata/network.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93
--- /dev/null
+++ b/hasura/metadata/network.yaml
@@ -0,0 +1 @@
+{}
diff --git a/hasura/metadata/opentelemetry.yaml b/hasura/metadata/opentelemetry.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93
--- /dev/null
+++ b/hasura/metadata/opentelemetry.yaml
@@ -0,0 +1 @@
+{}
diff --git a/hasura/metadata/query_collections.yaml b/hasura/metadata/query_collections.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fe51488c7066f6687ef680d6bfaa4f7768ef205c
--- /dev/null
+++ b/hasura/metadata/query_collections.yaml
@@ -0,0 +1 @@
+[]
diff --git a/hasura/metadata/remote_schemas.yaml b/hasura/metadata/remote_schemas.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fe51488c7066f6687ef680d6bfaa4f7768ef205c
--- /dev/null
+++ b/hasura/metadata/remote_schemas.yaml
@@ -0,0 +1 @@
+[]
diff --git a/hasura/metadata/rest_endpoints.yaml b/hasura/metadata/rest_endpoints.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fe51488c7066f6687ef680d6bfaa4f7768ef205c
--- /dev/null
+++ b/hasura/metadata/rest_endpoints.yaml
@@ -0,0 +1 @@
+[]
diff --git a/hasura/metadata/version.yaml b/hasura/metadata/version.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0a70affa4bdaac5b06bfd9793ffc20f5f60e9ea6
--- /dev/null
+++ b/hasura/metadata/version.yaml
@@ -0,0 +1 @@
+version: 3
diff --git a/hasura/migrations/default/1702976538494_init/up.sql b/hasura/migrations/default/1702976538494_init/up.sql
new file mode 100644
index 0000000000000000000000000000000000000000..67c869ebed7285e174b07fe49777ea24eb9fa2b7
--- /dev/null
+++ b/hasura/migrations/default/1702976538494_init/up.sql
@@ -0,0 +1,21 @@
+SET check_function_bodies = false;
+CREATE TABLE public.profiles (
+    address text NOT NULL,
+    avatar bytea,
+    description text,
+    geoloc point,
+    title text,
+    city text,
+    socials jsonb,
+    created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
+    updated_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP
+);
+CREATE FUNCTION public.bytea_to_base64(data_row public.profiles) RETURNS text
+    LANGUAGE plpgsql STABLE
+    AS $$
+BEGIN
+    RETURN ENCODE(data_row.avatar, 'base64');
+END;
+$$;
+ALTER TABLE ONLY public.profiles
+    ADD CONSTRAINT profiles_pkey PRIMARY KEY (address);
diff --git a/src/main.ts b/src/main.ts
index 5179324ab1ef7572bd4e73bf6e6df1210037d570..f8cbf195e914cbbb3a66e81b67b7c7b79ec5e9ce 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -37,7 +37,7 @@ pubsub.addEventListener('message', (message) => {
       const isValid = isValidSignature(bytesPayload, dag.sig, dag.pubk)
       if (isValid) {
         // here we would do the processing
-        addToIndex(cid, dag)
+        // addToIndex(cid, dag)
       } else {
         feed.value.push('[invalid sig] ' + msg)
       }
diff --git a/src/types.ts b/src/types.ts
index 8942d058cf54242dba41292f99303fe2e2c609ea..1e0bffee9608cecd1350511235d4cc184096c39b 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -21,6 +21,7 @@ export interface IndexRequest {
   /// kind of the document
   // the CID points to something describing the kind of the document
   // this allows to filter documents based on kinds of interest
+  // TODO allow number for more compact known kinds
   kind: CID
   /// data coming with the index request
   // only nullable field, useful for deletion document for example