diff --git a/index.html b/index.html
index 501fda6..461cf18 100644
--- a/index.html
+++ b/index.html
@@ -4,6 +4,7 @@
     <meta charset="UTF-8" />
     <link rel="icon" type="image/png" href="/favicon.png" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <link rel="manifest" href="/app.webmanifest" />
     <title>SIGit</title>
   </head>
   <body>
diff --git a/package-lock.json b/package-lock.json
index 6235019..4c6f81b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "sigit",
-  "version": "0.0.0-beta",
+  "version": "1.0.3",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "sigit",
-      "version": "0.0.0-beta",
+      "version": "1.0.3",
       "hasInstallScript": true,
       "license": "AGPL-3.0-or-later ",
       "dependencies": {
@@ -20,11 +20,11 @@
         "@mui/lab": "5.0.0-alpha.166",
         "@mui/material": "5.15.11",
         "@noble/hashes": "^1.4.0",
-        "@nostr-dev-kit/ndk": "2.10.0",
-        "@nostr-dev-kit/ndk-cache-dexie": "2.5.1",
+        "@nostr-dev-kit/ndk": "2.11.0",
+        "@nostr-dev-kit/ndk-cache-dexie": "2.5.9",
         "@pdf-lib/fontkit": "^1.1.1",
         "@reduxjs/toolkit": "2.2.1",
-        "axios": "^1.7.4",
+        "axios": "^1.8.2",
         "crypto-hash": "3.0.0",
         "crypto-js": "^4.2.0",
         "dexie": "4.0.8",
@@ -51,8 +51,7 @@
         "react-toastify": "10.0.4",
         "redux": "5.0.1",
         "signature_pad": "^5.0.4",
-        "tseep": "1.2.1",
-        "use-immer": "^0.11.0"
+        "tseep": "1.2.1"
       },
       "devDependencies": {
         "@saithodev/semantic-release-gitea": "^2.1.0",
@@ -109,12 +108,14 @@
       }
     },
     "node_modules/@babel/code-frame": {
-      "version": "7.23.5",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
-      "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+      "version": "7.26.2",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
+      "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
+      "license": "MIT",
       "dependencies": {
-        "@babel/highlight": "^7.23.4",
-        "chalk": "^2.4.2"
+        "@babel/helper-validator-identifier": "^7.25.9",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.0.0"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -306,17 +307,19 @@
       }
     },
     "node_modules/@babel/helper-string-parser": {
-      "version": "7.23.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
-      "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+      "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+      "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.22.20",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
-      "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+      "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+      "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
       }
@@ -331,37 +334,28 @@
       }
     },
     "node_modules/@babel/helpers": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz",
-      "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==",
+      "version": "7.27.0",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz",
+      "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@babel/template": "^7.23.9",
-        "@babel/traverse": "^7.23.9",
-        "@babel/types": "^7.23.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/highlight": {
-      "version": "7.23.4",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
-      "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
-      "dependencies": {
-        "@babel/helper-validator-identifier": "^7.22.20",
-        "chalk": "^2.4.2",
-        "js-tokens": "^4.0.0"
+        "@babel/template": "^7.27.0",
+        "@babel/types": "^7.27.0"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
-      "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
+      "version": "7.27.0",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz",
+      "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.27.0"
+      },
       "bin": {
         "parser": "bin/babel-parser.js"
       },
@@ -400,9 +394,10 @@
       }
     },
     "node_modules/@babel/runtime": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz",
-      "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==",
+      "version": "7.27.0",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
+      "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
+      "license": "MIT",
       "dependencies": {
         "regenerator-runtime": "^0.14.0"
       },
@@ -411,14 +406,15 @@
       }
     },
     "node_modules/@babel/template": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz",
-      "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==",
+      "version": "7.27.0",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
+      "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@babel/code-frame": "^7.23.5",
-        "@babel/parser": "^7.23.9",
-        "@babel/types": "^7.23.9"
+        "@babel/code-frame": "^7.26.2",
+        "@babel/parser": "^7.27.0",
+        "@babel/types": "^7.27.0"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -446,13 +442,13 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz",
-      "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==",
+      "version": "7.27.0",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz",
+      "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==",
+      "license": "MIT",
       "dependencies": {
-        "@babel/helper-string-parser": "^7.23.4",
-        "@babel/helper-validator-identifier": "^7.22.20",
-        "to-fast-properties": "^2.0.0"
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1698,15 +1694,13 @@
       }
     },
     "node_modules/@noble/secp256k1": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-2.0.0.tgz",
-      "integrity": "sha512-rUGBd95e2a45rlmFTqQJYEFA4/gdIARFfuTuTqLglz0PZ6AKyzyXsEZZq7UZn8hZsvaBgpCzKKBJizT2cJERXw==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://paulmillr.com/funding/"
-        }
-      ]
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-2.2.3.tgz",
+      "integrity": "sha512-l7r5oEQym9Us7EAigzg30/PQAvynhMt2uoYtT3t26eGDVm9Yii5mZ5jWSWmZ/oSIR2Et0xfc6DXrG0bZ787V3w==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
     },
     "node_modules/@nodelib/fs.scandir": {
       "version": "2.1.5",
@@ -1744,19 +1738,19 @@
       }
     },
     "node_modules/@nostr-dev-kit/ndk": {
-      "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/@nostr-dev-kit/ndk/-/ndk-2.10.0.tgz",
-      "integrity": "sha512-TqCAAo6ylORraAXrzRkCGFN2xTMiFbdER8Y8CtUT0HwOpFG/Wn+PBNeDeDmqkl/6LaPdeyXmVwCWj2KcUjIwYA==",
+      "version": "2.11.0",
+      "resolved": "https://registry.npmjs.org/@nostr-dev-kit/ndk/-/ndk-2.11.0.tgz",
+      "integrity": "sha512-FKIMtcVsVcquzrC+yir9lOXHCIHmQ3IKEVCMohqEB7N96HjP2qrI9s5utbjI3lkavFNF5tXg1Gp9ODEo7XCfLA==",
+      "license": "MIT",
       "dependencies": {
-        "@noble/curves": "^1.4.0",
-        "@noble/hashes": "^1.3.1",
-        "@noble/secp256k1": "^2.0.0",
-        "@scure/base": "^1.1.1",
-        "debug": "^4.3.4",
-        "light-bolt11-decoder": "^3.0.0",
-        "node-fetch": "^3.3.1",
+        "@noble/curves": "^1.6.0",
+        "@noble/hashes": "^1.5.0",
+        "@noble/secp256k1": "^2.1.0",
+        "@scure/base": "^1.1.9",
+        "debug": "^4.3.6",
+        "light-bolt11-decoder": "^3.2.0",
         "nostr-tools": "^2.7.1",
-        "tseep": "^1.1.1",
+        "tseep": "^1.2.2",
         "typescript-lru-cache": "^2.0.0",
         "utf8-buffer": "^1.0.0",
         "websocket-polyfill": "^0.0.3"
@@ -1766,17 +1760,41 @@
       }
     },
     "node_modules/@nostr-dev-kit/ndk-cache-dexie": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@nostr-dev-kit/ndk-cache-dexie/-/ndk-cache-dexie-2.5.1.tgz",
-      "integrity": "sha512-tUwEy68bd9GL5JVuZIjcpdwuDEBnaXen3WJ64/GRDtbyE1RB01Y6hHC7IQC9bcQ6SC7XBGyPd+2nuTyR7+Mffg==",
+      "version": "2.5.9",
+      "resolved": "https://registry.npmjs.org/@nostr-dev-kit/ndk-cache-dexie/-/ndk-cache-dexie-2.5.9.tgz",
+      "integrity": "sha512-SZ5FjON0QPekiC7oW9Hy3JQxG0Oxxtud9LBa1q/A49JV/Qppv1x37nFHxi0XLxEbDgFTNYbaN27Zjfp2NPem2g==",
+      "license": "MIT",
       "dependencies": {
-        "@nostr-dev-kit/ndk": "2.10.0",
-        "debug": "^4.3.4",
-        "dexie": "^4.0.2",
+        "@nostr-dev-kit/ndk": "2.11.0",
+        "debug": "^4.3.7",
+        "dexie": "^4.0.8",
         "nostr-tools": "^2.4.0",
         "typescript-lru-cache": "^2.0.0"
       }
     },
+    "node_modules/@nostr-dev-kit/ndk-cache-dexie/node_modules/debug": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@nostr-dev-kit/ndk-cache-dexie/node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "license": "MIT"
+    },
     "node_modules/@nostr-dev-kit/ndk/node_modules/@noble/curves": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.7.0.tgz",
@@ -1802,6 +1820,15 @@
         "url": "https://paulmillr.com/funding/"
       }
     },
+    "node_modules/@nostr-dev-kit/ndk/node_modules/@scure/base": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.4.tgz",
+      "integrity": "sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
     "node_modules/@nostr-dev-kit/ndk/node_modules/nostr-tools": {
       "version": "2.10.4",
       "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.10.4.tgz",
@@ -1859,6 +1886,24 @@
         "url": "https://paulmillr.com/funding/"
       }
     },
+    "node_modules/@nostr-dev-kit/ndk/node_modules/nostr-tools/node_modules/@scure/base": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz",
+      "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://paulmillr.com/funding/"
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/@nostr-dev-kit/ndk/node_modules/tseep": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/tseep/-/tseep-1.3.1.tgz",
+      "integrity": "sha512-ZPtfk1tQnZVyr7BPtbJ93qaAh2lZuIOpTMjhrYa4XctT8xe7t4SAW9LIxrySDuYMsfNNayE51E/WNGrNVgVicQ==",
+      "license": "MIT"
+    },
     "node_modules/@octokit/auth-token": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz",
@@ -1891,9 +1936,9 @@
       }
     },
     "node_modules/@octokit/endpoint": {
-      "version": "10.1.2",
-      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.2.tgz",
-      "integrity": "sha512-XybpFv9Ms4hX5OCHMZqyODYqGTZ3H6K6Vva+M9LR7ib/xr1y1ZnlChYv9H680y77Vd/i/k+thXApeRASBQkzhA==",
+      "version": "10.1.3",
+      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz",
+      "integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==",
       "dev": true,
       "license": "MIT",
       "peer": true,
@@ -1922,22 +1967,22 @@
       }
     },
     "node_modules/@octokit/openapi-types": {
-      "version": "23.0.1",
-      "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
-      "integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
+      "version": "24.2.0",
+      "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
+      "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
       "dev": true,
       "license": "MIT",
       "peer": true
     },
     "node_modules/@octokit/plugin-paginate-rest": {
-      "version": "11.4.0",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.0.tgz",
-      "integrity": "sha512-ttpGck5AYWkwMkMazNCZMqxKqIq1fJBNxBfsFwwfyYKTf914jKkLF0POMS3YkPBwp5g1c2Y4L79gDz01GhSr1g==",
+      "version": "11.6.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.6.0.tgz",
+      "integrity": "sha512-n5KPteiF7pWKgBIBJSk8qzoZWcUkza2O6A0za97pMGVrGfPdltxrfmfF5GucHYvHGZD8BdaZmmHGz5cX/3gdpw==",
       "dev": true,
       "license": "MIT",
       "peer": true,
       "dependencies": {
-        "@octokit/types": "^13.7.0"
+        "@octokit/types": "^13.10.0"
       },
       "engines": {
         "node": ">= 18"
@@ -1984,15 +2029,15 @@
       }
     },
     "node_modules/@octokit/request": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.0.tgz",
-      "integrity": "sha512-kXLfcxhC4ozCnAXy2ff+cSxpcF0A1UqxjvYMqNuPIeOAzJbVWQ+dy5G2fTylofB/gTbObT8O6JORab+5XtA1Kw==",
+      "version": "9.2.2",
+      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
+      "integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
       "dev": true,
       "license": "MIT",
       "peer": true,
       "dependencies": {
-        "@octokit/endpoint": "^10.0.0",
-        "@octokit/request-error": "^6.0.1",
+        "@octokit/endpoint": "^10.1.3",
+        "@octokit/request-error": "^6.1.7",
         "@octokit/types": "^13.6.2",
         "fast-content-type-parse": "^2.0.0",
         "universal-user-agent": "^7.0.2"
@@ -2002,9 +2047,9 @@
       }
     },
     "node_modules/@octokit/request-error": {
-      "version": "6.1.6",
-      "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.6.tgz",
-      "integrity": "sha512-pqnVKYo/at0NuOjinrgcQYpEbv4snvP3bKMRqHaD9kIsk9u1LCpb2smHZi8/qJfgeNqLo5hNW4Z7FezNdEo0xg==",
+      "version": "6.1.7",
+      "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
+      "integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
       "dev": true,
       "license": "MIT",
       "peer": true,
@@ -2016,14 +2061,14 @@
       }
     },
     "node_modules/@octokit/types": {
-      "version": "13.7.0",
-      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.7.0.tgz",
-      "integrity": "sha512-BXfRP+3P3IN6fd4uF3SniaHKOO4UXWBfkdR3vA8mIvaoO/wLjGN5qivUtW0QRitBHHMcfC41SLhNVYIZZE+wkA==",
+      "version": "13.10.0",
+      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
+      "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
       "dev": true,
       "license": "MIT",
       "peer": true,
       "dependencies": {
-        "@octokit/openapi-types": "^23.0.1"
+        "@octokit/openapi-types": "^24.2.0"
       }
     },
     "node_modules/@pdf-lib/fontkit": {
@@ -3814,6 +3859,7 @@
       "version": "3.2.1",
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
       "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
       "dependencies": {
         "color-convert": "^1.9.0"
       },
@@ -4003,9 +4049,9 @@
       }
     },
     "node_modules/axios": {
-      "version": "1.7.4",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
-      "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.2.tgz",
+      "integrity": "sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==",
       "license": "MIT",
       "dependencies": {
         "follow-redirects": "^1.15.6",
@@ -4516,6 +4562,7 @@
       "version": "2.4.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
       "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dev": true,
       "dependencies": {
         "ansi-styles": "^3.2.1",
         "escape-string-regexp": "^1.0.5",
@@ -4973,6 +5020,7 @@
       "version": "1.9.3",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
       "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
       "dependencies": {
         "color-name": "1.1.3"
       }
@@ -4980,7 +5028,8 @@
     "node_modules/color-name": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+      "dev": true
     },
     "node_modules/color-support": {
       "version": "1.1.3",
@@ -6141,14 +6190,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/data-uri-to-buffer": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
-      "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
-      "engines": {
-        "node": ">= 12"
-      }
-    },
     "node_modules/dateformat": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
@@ -6684,9 +6725,9 @@
       "dev": true
     },
     "node_modules/elliptic": {
-      "version": "6.6.0",
-      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.0.tgz",
-      "integrity": "sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==",
+      "version": "6.6.1",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz",
+      "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -6899,6 +6940,7 @@
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
       "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "dev": true,
       "engines": {
         "node": ">=0.8.0"
       }
@@ -7370,28 +7412,6 @@
         "reusify": "^1.0.4"
       }
     },
-    "node_modules/fetch-blob": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
-      "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/jimmywarting"
-        },
-        {
-          "type": "paypal",
-          "url": "https://paypal.me/jimmywarting"
-        }
-      ],
-      "dependencies": {
-        "node-domexception": "^1.0.0",
-        "web-streams-polyfill": "^3.0.3"
-      },
-      "engines": {
-        "node": "^12.20 || >= 14.13"
-      }
-    },
     "node_modules/figures": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
@@ -7570,17 +7590,6 @@
         "node": ">= 6"
       }
     },
-    "node_modules/formdata-polyfill": {
-      "version": "4.0.10",
-      "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
-      "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
-      "dependencies": {
-        "fetch-blob": "^3.1.2"
-      },
-      "engines": {
-        "node": ">=12.20.0"
-      }
-    },
     "node_modules/from2": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
@@ -8271,6 +8280,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
       "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "dev": true,
       "engines": {
         "node": ">=4"
       }
@@ -9180,9 +9190,10 @@
       }
     },
     "node_modules/light-bolt11-decoder": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/light-bolt11-decoder/-/light-bolt11-decoder-3.0.0.tgz",
-      "integrity": "sha512-AKvOigD2pmC8ktnn2TIqdJu0K0qk6ukUmTvHwF3JNkm8uWCqt18Ijn33A/a7gaRZ4PghJ59X+8+MXrzLKdBTmQ==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/light-bolt11-decoder/-/light-bolt11-decoder-3.2.0.tgz",
+      "integrity": "sha512-3QEofgiBOP4Ehs9BI+RkZdXZNtSys0nsJ6fyGeSiAGCBsMwHGUDS/JQlY/sTnWs91A2Nh0S9XXfA8Sy9g6QpuQ==",
+      "license": "MIT",
       "dependencies": {
         "@scure/base": "1.1.1"
       }
@@ -10257,24 +10268,6 @@
       "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
       "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
     },
-    "node_modules/node-domexception": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
-      "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/jimmywarting"
-        },
-        {
-          "type": "github",
-          "url": "https://paypal.me/jimmywarting"
-        }
-      ],
-      "engines": {
-        "node": ">=10.5.0"
-      }
-    },
     "node_modules/node-emoji": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz",
@@ -10306,23 +10299,6 @@
         "url": "https://github.com/sindresorhus/is?sponsor=1"
       }
     },
-    "node_modules/node-fetch": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
-      "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
-      "dependencies": {
-        "data-uri-to-buffer": "^4.0.0",
-        "fetch-blob": "^3.1.4",
-        "formdata-polyfill": "^4.0.10"
-      },
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/node-fetch"
-      }
-    },
     "node_modules/node-gyp-build": {
       "version": "4.8.0",
       "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz",
@@ -13906,7 +13882,6 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
       "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
-      "dev": true,
       "license": "ISC"
     },
     "node_modules/picomatch": {
@@ -16609,6 +16584,7 @@
       "version": "5.5.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
       "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
       "dependencies": {
         "has-flag": "^3.0.0"
       },
@@ -16877,14 +16853,6 @@
         "node": ">=0.6.0"
       }
     },
-    "node_modules/to-fast-properties": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
-      "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/to-readable-stream": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz",
@@ -17265,16 +17233,6 @@
       "dev": true,
       "license": "MIT"
     },
-    "node_modules/use-immer": {
-      "version": "0.11.0",
-      "resolved": "https://registry.npmjs.org/use-immer/-/use-immer-0.11.0.tgz",
-      "integrity": "sha512-RNAqi3GqsWJ4bcCd4LMBgdzvPmTABam24DUaFiKfX9s3MSorNRz9RDZYJkllJoMHUxVLMDetwAuCDeyWNrp1yA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "immer": ">=8.0.0",
-        "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0"
-      }
-    },
     "node_modules/use-sync-external-store": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
@@ -17347,9 +17305,9 @@
       }
     },
     "node_modules/vite": {
-      "version": "5.4.8",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
-      "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
+      "version": "5.4.16",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.16.tgz",
+      "integrity": "sha512-Y5gnfp4NemVfgOTDQAunSD4346fal44L9mszGGY/e+qxsRT5y1sMlS/8tiQ8AFAp+MFgYNSINdfEchJiPm41vQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -17462,14 +17420,6 @@
       "dev": true,
       "license": "MIT"
     },
-    "node_modules/web-streams-polyfill": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
-      "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
     "node_modules/webidl-conversions": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
diff --git a/package.json b/package.json
index f803726..69c59f4 100644
--- a/package.json
+++ b/package.json
@@ -31,11 +31,11 @@
     "@mui/lab": "5.0.0-alpha.166",
     "@mui/material": "5.15.11",
     "@noble/hashes": "^1.4.0",
-    "@nostr-dev-kit/ndk": "2.10.0",
-    "@nostr-dev-kit/ndk-cache-dexie": "2.5.1",
+    "@nostr-dev-kit/ndk": "2.11.0",
+    "@nostr-dev-kit/ndk-cache-dexie": "2.5.9",
     "@pdf-lib/fontkit": "^1.1.1",
     "@reduxjs/toolkit": "2.2.1",
-    "axios": "^1.7.4",
+    "axios": "^1.8.2",
     "crypto-hash": "3.0.0",
     "crypto-js": "^4.2.0",
     "dexie": "4.0.8",
@@ -62,8 +62,7 @@
     "react-toastify": "10.0.4",
     "redux": "5.0.1",
     "signature_pad": "^5.0.4",
-    "tseep": "1.2.1",
-    "use-immer": "^0.11.0"
+    "tseep": "1.2.1"
   },
   "devDependencies": {
     "@saithodev/semantic-release-gitea": "^2.1.0",
diff --git a/public/app.webmanifest b/public/app.webmanifest
new file mode 100644
index 0000000..c0b073f
--- /dev/null
+++ b/public/app.webmanifest
@@ -0,0 +1,58 @@
+{
+  "short_name": "SIGit",
+  "name": "SIGit",
+  "description": "A decentralised document signing tool",
+  "icons": [
+    {
+      "src": "favicon-512x512.png",
+      "sizes": "512x512",
+      "type": "image/png"
+    },
+    {
+      "src": "favicon-384x384.png",
+      "sizes": "384x384",
+      "type": "image/png"
+    },
+    {
+      "src": "favicon-256x256.png",
+      "sizes": "256x256",
+      "type": "image/png"
+    },
+    {
+      "src": "favicon-192x192.png",
+      "sizes": "192x192",
+      "type": "image/png"
+    },
+    {
+      "src": "favicon-144x144.png",
+      "sizes": "144x144",
+      "type": "image/png"
+    },
+    {
+      "src": "favicon-128x128.png",
+      "sizes": "128x128",
+      "type": "image/png"
+    },
+    {
+      "src": "favicon-96x96.png",
+      "sizes": "96x96",
+      "type": "image/png"
+    },
+    {
+      "src": "favicon-72x72.png",
+      "sizes": "72x72",
+      "type": "image/png"
+    },
+    {
+      "src": "favicon-64x64.png",
+      "sizes": "64x64",
+      "type": "image/png"
+    }
+  ],
+  "start_url": "/",
+  "display_override": ["minimal-ui", "standalone"],
+  "display": "minimal-ui",
+  "orientation": "any",
+  "theme_color": "#7d54a3",
+  "background_color": "#ffffff"
+}
diff --git a/public/favicon-128x128.png b/public/favicon-128x128.png
new file mode 100644
index 0000000..ada1e35
Binary files /dev/null and b/public/favicon-128x128.png differ
diff --git a/public/favicon-144x144.png b/public/favicon-144x144.png
new file mode 100644
index 0000000..d226bc3
Binary files /dev/null and b/public/favicon-144x144.png differ
diff --git a/public/favicon-192x192.png b/public/favicon-192x192.png
new file mode 100644
index 0000000..d5ce791
Binary files /dev/null and b/public/favicon-192x192.png differ
diff --git a/public/favicon-256x256.png b/public/favicon-256x256.png
new file mode 100644
index 0000000..b6a340f
Binary files /dev/null and b/public/favicon-256x256.png differ
diff --git a/public/favicon-384x384.png b/public/favicon-384x384.png
new file mode 100644
index 0000000..cc9872e
Binary files /dev/null and b/public/favicon-384x384.png differ
diff --git a/public/favicon-512x512.png b/public/favicon-512x512.png
new file mode 100644
index 0000000..fe48fe3
Binary files /dev/null and b/public/favicon-512x512.png differ
diff --git a/public/favicon-64x64.png b/public/favicon-64x64.png
new file mode 100644
index 0000000..d59e016
Binary files /dev/null and b/public/favicon-64x64.png differ
diff --git a/public/favicon-72x72.png b/public/favicon-72x72.png
new file mode 100644
index 0000000..168bb20
Binary files /dev/null and b/public/favicon-72x72.png differ
diff --git a/public/favicon-96x96.png b/public/favicon-96x96.png
new file mode 100644
index 0000000..5267e60
Binary files /dev/null and b/public/favicon-96x96.png differ
diff --git a/public/favicon.svg b/public/favicon.svg
new file mode 100644
index 0000000..144306d
--- /dev/null
+++ b/public/favicon.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 282.61 282.61">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #47b17d;
+      }
+
+      .cls-2 {
+        fill: #4c82a3;
+      }
+
+      .cls-3 {
+        fill: #7d54a3;
+      }
+    </style>
+  </defs>
+  <g id="Layer_1-2" data-name="Layer 1" transform="translate(0, 13.775)">
+    <g>
+      <path class="cls-2" d="M181.53,115.06h0c-9.4-36.67-56.77-24.79-121.09-12.57C-3.54,114.64-25.35,19.85,37.72,3.62,46.91,1.26,56.55,0,66.47,0c63.55,0,115.06,51.51,115.06,115.06Z"/>
+      <path class="cls-1" d="M100,140h0c9.4,36.67,56.77,24.79,121.09,12.57,63.98-12.16,85.79,82.64,22.72,98.86-9.19,2.36-18.83,3.62-28.76,3.62-63.55,0-115.06-51.51-115.06-115.06Z"/>
+      <circle class="cls-3" cx="140.77" cy="127.53" r="24.88"/>
+    </g>
+  </g>
+</svg>
\ No newline at end of file
diff --git a/src/App.tsx b/src/App.tsx
index 3829ba6..d10dc0d 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -4,8 +4,6 @@ import { Navigate, Route, Routes } from 'react-router-dom'
 import { useAppSelector, useAuth } from './hooks'
 
 import { MainLayout } from './layouts/Main'
-
-import { appPrivateRoutes, appPublicRoutes } from './routes'
 import {
   privateRoutes,
   publicRoutes,
@@ -16,7 +14,7 @@ import './App.scss'
 
 const App = () => {
   const { checkSession } = useAuth()
-  const authState = useAppSelector((state) => state.auth)
+  const isLoggedIn = useAppSelector((state) => state.auth?.loggedIn)
 
   useEffect(() => {
     if (window.location.hostname === '0.0.0.0') {
@@ -29,19 +27,9 @@ const App = () => {
     checkSession()
   }, [checkSession])
 
-  const handleRootRedirect = () => {
-    if (authState.loggedIn) return appPrivateRoutes.homePage
-
-    const callbackPathEncoded = btoa(
-      window.location.href.split(`${window.location.origin}/#`)[1]
-    )
-
-    return `${appPublicRoutes.landingPage}?callbackPath=${callbackPathEncoded}`
-  }
-
   // Hide route only if loggedIn and r.hiddenWhenLoggedIn are both true
   const publicRoutesList = recursiveRouteRenderer(publicRoutes, (r) => {
-    return !authState.loggedIn || !r.hiddenWhenLoggedIn
+    return !isLoggedIn || !r.hiddenWhenLoggedIn
   })
 
   const privateRouteList = recursiveRouteRenderer(privateRoutes)
@@ -49,9 +37,9 @@ const App = () => {
   return (
     <Routes>
       <Route element={<MainLayout />}>
-        {authState?.loggedIn && privateRouteList}
         {publicRoutesList}
-        <Route path="*" element={<Navigate to={handleRootRedirect()} />} />
+        {privateRouteList}
+        <Route path="*" element={<Navigate to={'/'} />} />
       </Route>
     </Routes>
   )
diff --git a/src/components/AppBar/AppBar.tsx b/src/components/AppBar/AppBar.tsx
index 68b04dd..e1c2220 100644
--- a/src/components/AppBar/AppBar.tsx
+++ b/src/components/AppBar/AppBar.tsx
@@ -181,7 +181,7 @@ export const AppBar = () => {
                       onClick={() => {
                         setAnchorElUser(null)
 
-                        navigate(appPrivateRoutes.settings)
+                        navigate(appPrivateRoutes.profileSettings)
                       }}
                       sx={{
                         justifyContent: 'center'
diff --git a/src/components/DisplaySigit/LocalDraftSigit.tsx b/src/components/DisplaySigit/LocalDraftSigit.tsx
new file mode 100644
index 0000000..f59da16
--- /dev/null
+++ b/src/components/DisplaySigit/LocalDraftSigit.tsx
@@ -0,0 +1,117 @@
+import { useState } from 'react'
+import { Link } from 'react-router-dom'
+import { Tooltip, Button, Divider } from '@mui/material'
+import {
+  faCalendar,
+  faFile,
+  faFileCircleExclamation,
+  faPen,
+  faTrash
+} from '@fortawesome/free-solid-svg-icons'
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
+import { SigitDraft, UserRole } from '../../types'
+import { appPrivateRoutes } from '../../routes'
+import {
+  formatTimestamp,
+  getSigitDraft,
+  npubToHex,
+  SigitStatus,
+  SignStatus
+} from '../../utils'
+import { DisplaySigner } from '../DisplaySigner'
+import { UserAvatarGroup } from '../UserAvatarGroup'
+import { getExtensionIconLabel } from '../getExtensionIconLabel'
+import { useAppSelector, useDidMount } from '../../hooks'
+import styles from './style.module.scss'
+
+interface LocalDraftSigitProps {
+  handleDraftDelete: () => void
+}
+export const LocalDraftSigit = ({
+  handleDraftDelete
+}: LocalDraftSigitProps) => {
+  const [draft, setDraft] = useState<SigitDraft>()
+  useDidMount(async () => {
+    // Check if draft exists and add link to direct
+    const draft = await getSigitDraft()
+    if (draft) {
+      setDraft(draft)
+    }
+  })
+  const submittedBy = useAppSelector((state) => state.auth.usersPubkey)
+
+  if (!draft) return null
+
+  const extensions = draft.files.map((f) => f.extension)
+  const isSame = extensions.every((e) => extensions[0] === e)
+
+  return (
+    <div className={styles.itemWrapper}>
+      <Link className={styles.insetLink} to={appPrivateRoutes.create}></Link>
+      <p className={`line-clamp-2 ${styles.title}`}>{draft.title}</p>
+      <div className={styles.users}>
+        {submittedBy && (
+          <DisplaySigner status={SignStatus.Pending} pubkey={submittedBy} />
+        )}
+        {submittedBy && draft.users.length ? (
+          <Divider orientation="vertical" flexItem />
+        ) : null}
+        <UserAvatarGroup max={7}>
+          {draft.users.map((user) => {
+            const pubkey = npubToHex(user.pubkey)!
+            return (
+              <DisplaySigner
+                key={pubkey}
+                status={
+                  user.role === UserRole.signer
+                    ? SignStatus.Pending
+                    : SignStatus.Viewer
+                }
+                pubkey={pubkey}
+              />
+            )
+          })}
+        </UserAvatarGroup>
+      </div>
+      <div className={`${styles.details} ${styles.iconLabel}`}>
+        <FontAwesomeIcon icon={faCalendar} />
+        {formatTimestamp(draft.lastUpdated)}
+      </div>
+      <div className={`${styles.details} ${styles.status}`}>
+        <span className={styles.iconLabel}>
+          <FontAwesomeIcon icon={faPen} /> {SigitStatus.LocalDraft}
+        </span>
+        {extensions.length > 0 ? (
+          <span className={styles.iconLabel}>
+            {!isSame ? (
+              <>
+                <FontAwesomeIcon icon={faFile} /> Multiple File Types
+              </>
+            ) : (
+              getExtensionIconLabel(extensions[0])
+            )}
+          </span>
+        ) : (
+          <>
+            <FontAwesomeIcon icon={faFileCircleExclamation} /> &mdash;
+          </>
+        )}
+      </div>
+      <div className={styles.itemActions}>
+        <Tooltip title="Delete" arrow placement="top" disableInteractive>
+          <Button
+            onClick={handleDraftDelete}
+            sx={{
+              color: 'var(--primary-main)',
+              minWidth: '34px',
+              padding: '10px'
+            }}
+            variant={'text'}
+          >
+            <FontAwesomeIcon icon={faTrash} />
+          </Button>
+        </Tooltip>
+      </div>
+    </div>
+  )
+}
diff --git a/src/components/DisplaySigit/index.tsx b/src/components/DisplaySigit/index.tsx
index 5147b45..20550b3 100644
--- a/src/components/DisplaySigit/index.tsx
+++ b/src/components/DisplaySigit/index.tsx
@@ -112,32 +112,37 @@ export const DisplaySigit = ({
           </>
         )}
       </div>
-      <div className={styles.itemActions}>
-        <Tooltip title="Duplicate" arrow placement="top" disableInteractive>
-          <Button
-            sx={{
-              color: 'var(--primary-main)',
-              minWidth: '34px',
-              padding: '10px'
-            }}
-            variant={'text'}
-          >
-            <FontAwesomeIcon icon={faCopy} />
-          </Button>
-        </Tooltip>
-        <Tooltip title="Archive" arrow placement="top" disableInteractive>
-          <Button
-            sx={{
-              color: 'var(--primary-main)',
-              minWidth: '34px',
-              padding: '10px'
-            }}
-            variant={'text'}
-          >
-            <FontAwesomeIcon icon={faArchive} />
-          </Button>
-        </Tooltip>
-      </div>
+      {
+        // TODO: enable buttons once feature is ready
+        false && (
+          <div className={styles.itemActions}>
+            <Tooltip title="Duplicate" arrow placement="top" disableInteractive>
+              <Button
+                sx={{
+                  color: 'var(--primary-main)',
+                  minWidth: '34px',
+                  padding: '10px'
+                }}
+                variant={'text'}
+              >
+                <FontAwesomeIcon icon={faCopy} />
+              </Button>
+            </Tooltip>
+            <Tooltip title="Archive" arrow placement="top" disableInteractive>
+              <Button
+                sx={{
+                  color: 'var(--primary-main)',
+                  minWidth: '34px',
+                  padding: '10px'
+                }}
+                variant={'text'}
+              >
+                <FontAwesomeIcon icon={faArchive} />
+              </Button>
+            </Tooltip>
+          </div>
+        )
+      }
     </div>
   )
 }
diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx
index 71fef1c..ee39939 100644
--- a/src/components/DrawPDFFields/index.tsx
+++ b/src/components/DrawPDFFields/index.tsx
@@ -18,7 +18,6 @@ import { FONT_SIZE, FONT_TYPE, inPx } from '../../utils/pdf'
 import { useScale } from '../../hooks/useScale'
 import { AvatarIconButton } from '../UserAvatarIconButton'
 import { UserAvatar } from '../UserAvatar'
-import { Updater } from 'use-immer'
 import { FileItem } from './internal/FileItem'
 import { FileDivider } from '../FileDivider'
 import { Counterpart } from './internal/Counterpart'
@@ -28,6 +27,7 @@ const MINIMUM_RECT_SIZE = {
   height: 10
 } as const
 import { NDKUserProfile } from '@nostr-dev-kit/ndk'
+import _ from 'lodash'
 
 const DEFAULT_START_SIZE = {
   width: 140,
@@ -45,7 +45,7 @@ interface DrawPdfFieldsProps {
   users: User[]
   userProfiles: { [key: string]: NDKUserProfile }
   sigitFiles: SigitFile[]
-  updateSigitFiles: Updater<SigitFile[]>
+  setSigitFiles: React.Dispatch<React.SetStateAction<SigitFile[]>>
   selectedTool?: DrawTool
 }
 
@@ -53,11 +53,10 @@ export const DrawPDFFields = ({
   selectedTool,
   userProfiles,
   sigitFiles,
-  updateSigitFiles,
+  setSigitFiles,
   users
 }: DrawPdfFieldsProps) => {
   const { to, from } = useScale()
-
   const signers = users.filter((u) => u.role === UserRole.signer)
   const defaultSignerNpub = signers.length ? hexToNpub(signers[0].pubkey) : ''
   const [lastSigner, setLastSigner] = useState(defaultSignerNpub)
@@ -354,8 +353,10 @@ export const DrawPDFFields = ({
   ) => {
     event.stopPropagation()
 
-    updateSigitFiles((draft) => {
-      draft[fileIndex]?.pages![pageIndex]?.drawnFields?.splice(fieldIndex, 1)
+    setSigitFiles((prev) => {
+      const clone = _.cloneDeep(prev)
+      clone[fileIndex]?.pages![pageIndex]?.drawnFields?.splice(fieldIndex, 1)
+      return clone
     })
   }
 
@@ -416,22 +417,28 @@ export const DrawPDFFields = ({
 
         // Add new drawn field to the files
         if (mouseState.clicked) {
-          updateSigitFiles((draft) => {
-            draft[fileIndex].pages![pageIndex].drawnFields.push(field)
+          setSigitFiles((prev) => {
+            const clone = _.cloneDeep(prev)
+            clone[fileIndex].pages![pageIndex].drawnFields.push(field)
+            return clone
           })
         }
 
         // Move
         if (mouseState.dragging) {
-          updateSigitFiles((draft) => {
-            draft[fileIndex].pages![pageIndex].drawnFields[fieldIndex!] = field
+          setSigitFiles((prev) => {
+            const clone = _.cloneDeep(prev)
+            clone[fileIndex].pages![pageIndex].drawnFields[fieldIndex!] = field
+            return clone
           })
         }
 
         // Resize
         if (mouseState.resizing) {
-          updateSigitFiles((draft) => {
-            draft[fileIndex].pages![pageIndex].drawnFields[fieldIndex!] = field
+          setSigitFiles((prev) => {
+            const clone = _.cloneDeep(prev)
+            clone[fileIndex].pages![pageIndex].drawnFields[fieldIndex!] = field
+            return clone
           })
         }
 
@@ -446,7 +453,7 @@ export const DrawPDFFields = ({
     mouseState.clicked,
     mouseState.dragging,
     mouseState.resizing,
-    updateSigitFiles
+    setSigitFiles
   ])
 
   /**
diff --git a/src/components/MarkTypeStrategy/DateTime/Input.tsx b/src/components/MarkTypeStrategy/DateTime/Input.tsx
new file mode 100644
index 0000000..b2e864c
--- /dev/null
+++ b/src/components/MarkTypeStrategy/DateTime/Input.tsx
@@ -0,0 +1,24 @@
+import { MarkInputProps } from '../MarkStrategy'
+import styles from '../../MarkFormField/style.module.scss'
+import { useEffect, useRef } from 'react'
+
+export const MarkInputDateTime = ({ handler, placeholder }: MarkInputProps) => {
+  const ref = useRef<HTMLInputElement>(null)
+  useEffect(() => {
+    if (ref.current) {
+      const date = new Date()
+      ref.current.value = date.toISOString().slice(0, 16)
+      handler(date.toUTCString())
+    }
+  }, [handler])
+  return (
+    <input
+      type="datetime-local"
+      ref={ref}
+      className={styles.input}
+      placeholder={placeholder}
+      readOnly={true}
+      disabled={true}
+    />
+  )
+}
diff --git a/src/components/MarkTypeStrategy/DateTime/index.tsx b/src/components/MarkTypeStrategy/DateTime/index.tsx
new file mode 100644
index 0000000..1892d49
--- /dev/null
+++ b/src/components/MarkTypeStrategy/DateTime/index.tsx
@@ -0,0 +1,7 @@
+import { MarkStrategy } from '../MarkStrategy'
+import { MarkInputDateTime } from './Input'
+
+export const DateTimeStrategy: MarkStrategy = {
+  input: MarkInputDateTime,
+  render: ({ value }) => <>{value}</>
+}
diff --git a/src/components/MarkTypeStrategy/FullName/Input.tsx b/src/components/MarkTypeStrategy/FullName/Input.tsx
new file mode 100644
index 0000000..7b63ae6
--- /dev/null
+++ b/src/components/MarkTypeStrategy/FullName/Input.tsx
@@ -0,0 +1,20 @@
+import { useDidMount } from '../../../hooks'
+import { useLocalStorage } from '../../../hooks/useLocalStorage'
+import { MarkInputProps } from '../MarkStrategy'
+import { MarkInputText } from '../Text/Input'
+
+export const MarkInputFullName = (props: MarkInputProps) => {
+  const [fullName, setFullName] = useLocalStorage('mark-fullname', '')
+  useDidMount(() => {
+    props.handler(fullName)
+  })
+  return MarkInputText({
+    ...props,
+    placeholder: 'Full Name',
+    value: fullName,
+    handler: (value) => {
+      setFullName(value)
+      props.handler(value)
+    }
+  })
+}
diff --git a/src/components/MarkTypeStrategy/FullName/index.tsx b/src/components/MarkTypeStrategy/FullName/index.tsx
new file mode 100644
index 0000000..1574c42
--- /dev/null
+++ b/src/components/MarkTypeStrategy/FullName/index.tsx
@@ -0,0 +1,7 @@
+import { MarkStrategy } from '../MarkStrategy'
+import { MarkInputFullName } from './Input'
+
+export const FullNameStrategy: MarkStrategy = {
+  input: MarkInputFullName,
+  render: ({ value }) => <>{value}</>
+}
diff --git a/src/components/MarkTypeStrategy/JobTitle/Input.tsx b/src/components/MarkTypeStrategy/JobTitle/Input.tsx
new file mode 100644
index 0000000..47d2969
--- /dev/null
+++ b/src/components/MarkTypeStrategy/JobTitle/Input.tsx
@@ -0,0 +1,20 @@
+import { useDidMount } from '../../../hooks'
+import { useLocalStorage } from '../../../hooks/useLocalStorage'
+import { MarkInputProps } from '../MarkStrategy'
+import { MarkInputText } from '../Text/Input'
+
+export const MarkInputJobTitle = (props: MarkInputProps) => {
+  const [jobTitle, setjobTitle] = useLocalStorage('mark-jobtitle', '')
+  useDidMount(() => {
+    props.handler(jobTitle)
+  })
+  return MarkInputText({
+    ...props,
+    placeholder: 'Job Title',
+    value: jobTitle,
+    handler: (value) => {
+      setjobTitle(value)
+      props.handler(value)
+    }
+  })
+}
diff --git a/src/components/MarkTypeStrategy/JobTitle/index.tsx b/src/components/MarkTypeStrategy/JobTitle/index.tsx
new file mode 100644
index 0000000..11f5d60
--- /dev/null
+++ b/src/components/MarkTypeStrategy/JobTitle/index.tsx
@@ -0,0 +1,7 @@
+import { MarkStrategy } from '../MarkStrategy'
+import { MarkInputJobTitle } from './Input'
+
+export const JobTitleStrategy: MarkStrategy = {
+  input: MarkInputJobTitle,
+  render: ({ value }) => <>{value}</>
+}
diff --git a/src/components/MarkTypeStrategy/MarkStrategy.tsx b/src/components/MarkTypeStrategy/MarkStrategy.tsx
index 562302e..0ca0ebc 100644
--- a/src/components/MarkTypeStrategy/MarkStrategy.tsx
+++ b/src/components/MarkTypeStrategy/MarkStrategy.tsx
@@ -2,6 +2,9 @@ import { MarkType } from '../../types/drawing'
 import { CurrentUserMark, Mark } from '../../types/mark'
 import { TextStrategy } from './Text'
 import { SignatureStrategy } from './Signature'
+import { FullNameStrategy } from './FullName'
+import { JobTitleStrategy } from './JobTitle'
+import { DateTimeStrategy } from './DateTime'
 
 export interface MarkInputProps {
   value: string
@@ -28,5 +31,8 @@ export type MarkStrategies = {
 
 export const MARK_TYPE_CONFIG: MarkStrategies = {
   [MarkType.TEXT]: TextStrategy,
-  [MarkType.SIGNATURE]: SignatureStrategy
+  [MarkType.SIGNATURE]: SignatureStrategy,
+  [MarkType.FULLNAME]: FullNameStrategy,
+  [MarkType.JOBTITLE]: JobTitleStrategy,
+  [MarkType.DATETIME]: DateTimeStrategy
 }
diff --git a/src/components/PDFView/style.module.scss b/src/components/PDFView/style.module.scss
index 61983d7..92c044e 100644
--- a/src/components/PDFView/style.module.scss
+++ b/src/components/PDFView/style.module.scss
@@ -8,6 +8,4 @@
   position: absolute;
   z-index: 40;
   display: flex;
-  justify-content: center;
-  align-items: center;
 }
diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts
index e0e75fb..7199a51 100644
--- a/src/hooks/useAuth.ts
+++ b/src/hooks/useAuth.ts
@@ -56,8 +56,7 @@ export const useAuth = () => {
    * method will be chosen (extension or keys)
    *
    * @param pubkey of the user trying to login
-   * @returns url to redirect if authentication successfull
-   * or error if otherwise
+   * @returns url to redirect if user has no relays set
    */
   const authAndGetMetadataAndRelaysMap = useCallback(
     async (pubkey: string) => {
@@ -108,7 +107,7 @@ export const useAuth = () => {
         dispatch(setRelayMapAction(relayMap))
       }
 
-      return appPrivateRoutes.homePage
+      return
     },
     [
       dispatch,
diff --git a/src/hooks/useLocalStorage.ts b/src/hooks/useLocalStorage.ts
new file mode 100644
index 0000000..a2a9532
--- /dev/null
+++ b/src/hooks/useLocalStorage.ts
@@ -0,0 +1,72 @@
+import React, { useMemo } from 'react'
+import {
+  getLocalStorageItem,
+  mergeWithInitialValue,
+  removeLocalStorageItem,
+  setLocalStorageItem
+} from '../utils'
+
+/**
+ * Subscribe to the Browser's storage event. Get the new value if any of the tabs changes it.
+ * @param callback - function to be called when the storage event is triggered
+ * @returns clean up function
+ */
+const useLocalStorageSubscribe = (callback: () => void) => {
+  window.addEventListener('storage', callback)
+  return () => window.removeEventListener('storage', callback)
+}
+
+export function useLocalStorage<T>(
+  key: string,
+  initialValue: T
+): [T, React.Dispatch<React.SetStateAction<T>>] {
+  const getSnapshot = () => {
+    // Get the stored value
+    const storedValue = getLocalStorageItem(key, initialValue)
+
+    // Parse the value
+    const parsedStoredValue = JSON.parse(storedValue)
+
+    // Merge the default and the stored in case some of the required fields are missing
+    return JSON.stringify(
+      mergeWithInitialValue(parsedStoredValue, initialValue)
+    )
+  }
+
+  // https://react.dev/reference/react/useSyncExternalStore
+  // Returns the snapshot of the data and subscribes to the storage event
+  const data = React.useSyncExternalStore(useLocalStorageSubscribe, getSnapshot)
+
+  // Takes the value or a function that returns the value and updates the local storage
+  const setState: React.Dispatch<React.SetStateAction<T>> = React.useCallback(
+    (v: React.SetStateAction<T>) => {
+      try {
+        const nextState =
+          typeof v === 'function'
+            ? (v as (prevState: T) => T)(JSON.parse(data))
+            : v
+
+        if (nextState === undefined || nextState === null) {
+          removeLocalStorageItem(key)
+        } else {
+          setLocalStorageItem(key, JSON.stringify(nextState))
+        }
+      } catch (e) {
+        console.warn(e)
+      }
+    },
+    [data, key]
+  )
+
+  React.useEffect(() => {
+    // Set local storage only when it's empty
+    const data = window.localStorage.getItem(key)
+    if (data === null) {
+      setLocalStorageItem(key, JSON.stringify(initialValue))
+    }
+  }, [key, initialValue])
+
+  const memoized = useMemo(() => JSON.parse(data) as T, [data])
+
+  return [memoized, setState]
+}
diff --git a/src/hooks/useNDK.ts b/src/hooks/useNDK.ts
index ad9e54f..c6ec41d 100644
--- a/src/hooks/useNDK.ts
+++ b/src/hooks/useNDK.ts
@@ -12,7 +12,9 @@ import {
 import _ from 'lodash'
 import {
   Event,
+  finalizeEvent,
   generateSecretKey,
+  getEventHash,
   getPublicKey,
   kinds,
   UnsignedEvent
@@ -40,17 +42,21 @@ import {
   getDTagForUserAppData,
   getUserAppDataFromBlossom,
   hexToNpub,
+  nip44Encrypt,
   parseJson,
+  randomTimeUpTo2DaysInThePast,
   SIGIT_RELAY,
   unixNow,
   uploadUserAppDataToBlossom
 } from '../utils'
+import { SendDMError, SendDMErrorType } from '../types/errors/SendDMError'
 
 export const useNDK = () => {
   const dispatch = useAppDispatch()
   const {
     ndk,
     fetchEvent,
+    fetchEventFromUserRelays,
     fetchEventsFromUserRelays,
     publish,
     getNDKRelayList
@@ -503,10 +509,139 @@ export const useNDK = () => {
     [ndk, usersPubkey, getNDKRelayList]
   )
 
+  /**
+   * Modified {@link UnsignedEvent Unsigned Event} that includes an id
+   *
+   * Fields id and created_at are required.
+   * @see {@link UnsignedEvent}
+   * @see {@link https://github.com/nostr-protocol/nips/blob/master/17.md#direct-message-kind}
+   */
+  type UnsignedEventWithId = UnsignedEvent & {
+    id?: string
+  }
+  const sendPrivateDirectMessage = useCallback(
+    async (message: string, receiver: string, subject?: string) => {
+      if (!receiver) throw new SendDMError(SendDMErrorType.MISSING_RECIEVER)
+
+      // Get the direct message preferred relays list
+      // https://github.com/nostr-protocol/nips/blob/master/17.md#publishing
+      const preferredRelaysListEvent = await fetchEventFromUserRelays(
+        {
+          kinds: [NDKKind.DirectMessageReceiveRelayList],
+          authors: [receiver]
+        },
+        receiver,
+        UserRelaysType.Read
+      )
+
+      const isRelayTag = (tag: string[]): boolean => tag[0] === 'relay'
+      const finalRelaysList: string[] = []
+      if (preferredRelaysListEvent) {
+        const preferredRelaysList = preferredRelaysListEvent.tags
+          .filter((t) => isRelayTag(t))
+          .map((t) => t[1])
+
+        finalRelaysList.push(...preferredRelaysList)
+      }
+
+      if (!finalRelaysList.length) {
+        // Get receiver's read relay list
+        const ndkRelayList = await getNDKRelayList(receiver).catch((err) => {
+          // Log an error if retrieving relay list metadata fails
+          console.log(
+            `An error occurred while finding relay list metadata for ${hexToNpub(receiver)}`,
+            err
+          )
+          return null
+        })
+        if (ndkRelayList?.readRelayUrls) {
+          finalRelaysList.push(...ndkRelayList.readRelayUrls)
+        }
+      }
+
+      if (!finalRelaysList.includes(SIGIT_RELAY)) {
+        finalRelaysList.push(SIGIT_RELAY)
+      }
+
+      // Generate "sender"
+      const senderSecret = generateSecretKey()
+      const senderPubkey = getPublicKey(senderSecret)
+
+      // Prepare tags for the message
+      const tags: string[][] = [['p', receiver]]
+
+      // Conversation title
+      if (subject) tags.push(['subject', subject])
+
+      // Create private DM event containing the message and relevant metadata
+      // TODO: kinds.PrivateDirectMessage (unavailabe in nostr-tools 10/10/2024 at v2.7.0)
+      const dm: UnsignedEventWithId = {
+        pubkey: senderPubkey,
+        created_at: unixNow(),
+        kind: 14,
+        tags,
+        content: message
+      }
+
+      // Calculate the hash based on the UnverifiedEvent
+      dm.id = getEventHash(dm)
+
+      // Encrypt the private dm using the sender secret and the receiver's public key
+      const encryptedDm = nip44Encrypt(dm, senderSecret, receiver)
+      if (!encryptedDm) {
+        throw new SendDMError(SendDMErrorType.ENCRYPTION_FAILED, {
+          context: {
+            receiver,
+            message,
+            kind: dm.kind
+          }
+        })
+      }
+
+      // Seal the message
+      // TODO: kinds.Seal (unavailabe in nostr-tools 10/10/2024 at v2.7.0)
+      const sealedMessage: UnsignedEvent = {
+        kind: 13, // seal
+        pubkey: senderPubkey,
+        content: encryptedDm,
+        created_at: randomTimeUpTo2DaysInThePast(),
+        tags: [] // no tags
+      }
+
+      // Finalize and sign the sealed event
+      const finalizedSeal = finalizeEvent(sealedMessage, senderSecret)
+
+      // Encrypt the seal and gift wrap
+      const finalizedGiftWrap = createWrap(finalizedSeal, receiver)
+
+      const ndkEvent = new NDKEvent(ndk, finalizedGiftWrap)
+
+      // Publish the finalized gift wrap event (the encrypted DM) to the relays
+      const publishedOnRelays = await ndkEvent.publish(
+        NDKRelaySet.fromRelayUrls(finalRelaysList, ndk, true)
+      )
+
+      // Handle cases where publishing to the relays failed
+      if (publishedOnRelays.size === 0) {
+        throw new SendDMError(SendDMErrorType.ENCRYPTION_FAILED, {
+          context: {
+            receiver,
+            count: publishedOnRelays.size
+          }
+        })
+      }
+
+      // Return true indicating that the DM was successfully sent
+      return true
+    },
+    [fetchEventFromUserRelays, getNDKRelayList, ndk]
+  )
+
   return {
     getUsersAppData,
     subscribeForSigits,
     updateUsersAppData,
-    sendNotification
+    sendNotification,
+    sendPrivateDirectMessage
   }
 }
diff --git a/src/layouts/Main.tsx b/src/layouts/Main.tsx
index 85daf75..2106931 100644
--- a/src/layouts/Main.tsx
+++ b/src/layouts/Main.tsx
@@ -1,16 +1,11 @@
 import { useCallback, useEffect, useRef, useState } from 'react'
 import { Outlet, useNavigate, useSearchParams } from 'react-router-dom'
-
 import { getPublicKey, nip19 } from 'nostr-tools'
-
 import { init as initNostrLogin } from 'nostr-login'
 import { NostrLoginAuthOptions } from 'nostr-login/dist/types'
-
 import { AppBar } from '../components/AppBar/AppBar'
 import { LoadingSpinner } from '../components/LoadingSpinner'
-
 import { NostrController } from '../controllers'
-
 import {
   useAppDispatch,
   useAppSelector,
@@ -19,7 +14,6 @@ import {
   useNDK,
   useNDKContext
 } from '../hooks'
-
 import {
   restoreState,
   setUserProfile,
@@ -30,9 +24,7 @@ import {
   setUserRobotImage
 } from '../store/actions'
 import { LoginMethod } from '../store/auth/types'
-
 import { getRoboHashPicture, loadState } from '../utils'
-
 import styles from './style.module.scss'
 
 export const MainLayout = () => {
@@ -53,29 +45,32 @@ export const MainLayout = () => {
   // Ref to track if `subscribeForSigits` has been called
   const hasSubscribed = useRef(false)
 
-  const navigateAfterLogin = (path: string) => {
-    const callbackPath = searchParams.get('callbackPath')
-
-    if (callbackPath) {
-      // base64 decoded path
-      const path = atob(callbackPath)
-      navigate(path)
-      return
-    }
-
-    navigate(path)
-  }
+  const navigateAfterLogin = useCallback(
+    (path: string | undefined) => {
+      const isCallback = window.location.hash.startsWith('#/?callbackPath=')
+      if (isCallback) {
+        const path = atob(window.location.hash.replace('#/?callbackPath=', ''))
+        setSearchParams((prev) => {
+          prev.delete('callbackPath')
+          return prev
+        })
+        navigate(path)
+        return
+      }
+      if (path) navigate(path)
+    },
+    [navigate, setSearchParams]
+  )
 
   const login = useCallback(async () => {
-    dispatch(updateLoginMethod(LoginMethod.nostrLogin))
-
-    const nostrController = NostrController.getInstance()
-    const pubkey = await nostrController.capturePublicKey()
-
-    const redirectPath = await authAndGetMetadataAndRelaysMap(pubkey)
-
-    if (redirectPath) {
+    try {
+      dispatch(updateLoginMethod(LoginMethod.nostrLogin))
+      const nostrController = NostrController.getInstance()
+      const pubkey = await nostrController.capturePublicKey()
+      const redirectPath = await authAndGetMetadataAndRelaysMap(pubkey)
       navigateAfterLogin(redirectPath)
+    } catch (error) {
+      console.error(`Error occured during login`, error)
     }
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [dispatch])
diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx
index d5424a9..2bb0642 100644
--- a/src/pages/create/index.tsx
+++ b/src/pages/create/index.tsx
@@ -45,7 +45,12 @@ import {
   uploadToFileStorage,
   DEFAULT_TOOLBOX,
   settleAllFullfilfedPromises,
-  uploadMetaToFileStorage
+  parseNostrEvent,
+  uploadMetaToFileStorage,
+  clearSigitDraft,
+  saveSigitDraft,
+  getSigitDraft,
+  timeout
 } from '../../utils'
 import { Container } from '../../components/Container'
 import fileListStyles from '../../components/FileList/style.module.scss'
@@ -72,13 +77,14 @@ import { getSigitFile, SigitFile } from '../../utils/file.ts'
 import { generateTimestamp } from '../../utils/opentimestamps.ts'
 import { Autocomplete } from '@mui/material'
 import _, { truncate } from 'lodash'
+import { SendDMError } from '../../types/errors/SendDMError.ts'
 import * as React from 'react'
 import { AvatarIconButton } from '../../components/UserAvatarIconButton'
 import { NDKUserProfile, NostrEvent } from '@nostr-dev-kit/ndk'
 import { useNDKContext } from '../../hooks/useNDKContext.ts'
 import { useNDK } from '../../hooks/useNDK.ts'
-import { useImmer } from 'use-immer'
 import { ButtonUnderline } from '../../components/ButtonUnderline/index.tsx'
+import { TimeoutError } from '../../types/errors/TimeoutError.ts'
 
 type FoundUser = NostrEvent & { npub: string }
 
@@ -86,7 +92,8 @@ export const CreatePage = () => {
   const navigate = useNavigate()
   const location = useLocation()
   const { findMetadata, fetchEventsFromUserRelays } = useNDKContext()
-  const { updateUsersAppData, sendNotification } = useNDK()
+  const { updateUsersAppData, sendNotification, sendPrivateDirectMessage } =
+    useNDK()
 
   const { uploadedFiles } = location.state || {}
   const [currentFile, setCurrentFile] = useState<File>()
@@ -97,7 +104,9 @@ export const CreatePage = () => {
 
   const [title, setTitle] = useState(`sigit_${formatTimestamp(Date.now())}`)
 
-  const [selectedFiles, setSelectedFiles] = useState<File[]>([...uploadedFiles])
+  const [selectedFiles, setSelectedFiles] = useState<File[]>([
+    ...(uploadedFiles || [])
+  ])
   const fileInputRef = useRef<HTMLInputElement>(null)
   const handleUploadButtonClick = () => {
     if (fileInputRef.current) {
@@ -123,7 +132,7 @@ export const CreatePage = () => {
     [key: string]: NDKUserProfile
   }>({})
 
-  const [drawnFiles, updateDrawnFiles] = useImmer<SigitFile[]>([])
+  const [drawnFiles, setDrawnFiles] = useState<SigitFile[]>([])
   const [parsingPdf, setIsParsing] = useState<boolean>(false)
 
   const searchFieldRef = useRef<HTMLInputElement>(null)
@@ -162,8 +171,8 @@ export const CreatePage = () => {
     return pubkey
   }
 
-  const handleSearchUsers = async (searchValue?: string) => {
-    const searchString = searchValue || userSearchInput || undefined
+  const handleSearchUsers = async () => {
+    const searchString = userSearchInput || undefined
 
     if (!searchString) return
 
@@ -171,14 +180,17 @@ export const CreatePage = () => {
 
     const searchTerm = searchString.trim()
 
-    fetchEventsFromUserRelays(
-      {
-        kinds: [0],
-        search: searchTerm
-      },
-      usersPubkey,
-      UserRelaysType.Write
-    )
+    Promise.race([
+      fetchEventsFromUserRelays(
+        {
+          kinds: [0],
+          search: searchTerm
+        },
+        usersPubkey,
+        UserRelaysType.Write
+      ),
+      timeout(30000)
+    ])
       .then((events) => {
         const nostrEvents = events.map((event) => event.rawEvent())
 
@@ -216,6 +228,9 @@ export const CreatePage = () => {
           toast.info('No user found with the provided search term')
       })
       .catch((error) => {
+        if (error instanceof TimeoutError) {
+          toast.error('Search timed out. Please try again.')
+        }
         console.error(error)
       })
       .finally(() => {
@@ -245,22 +260,23 @@ export const CreatePage = () => {
 
       // If pasted user npub of nip05 is present, we just add the user to the counterparts list
       if (pastedUserNpubOrNip05) {
-        setUserInput(pastedUserNpubOrNip05)
+        setUserInput(pastedUserNpubOrNip05.trim())
         setPastedUserNpubOrNip05(undefined)
       } else {
-        // Otherwize if search already provided some results, user must manually click the search button
+        // Otherwise if search already provided some results, user must manually click the search button
         if (!foundUsers.length) {
+          const searchTerm = userSearchInput.trim()
           // If it's NIP05 (includes @ or is a valid domain) send request to .well-known
           const domainRegex = /^[a-zA-Z0-9@.-]+\.[a-zA-Z]{2,}$/
-          if (domainRegex.test(userSearchInput)) {
+          if (searchTerm.startsWith('_@') || domainRegex.test(searchTerm)) {
             setSearchUsersLoading(true)
 
-            const pubkey = await handleSearchUserNip05(userSearchInput)
+            const pubkey = await handleSearchUserNip05(searchTerm)
 
             setSearchUsersLoading(false)
 
             if (pubkey) {
-              setUserInput(userSearchInput)
+              setUserInput(searchTerm)
             } else {
               toast.error(`No user found with the NIP05: ${userSearchInput}`)
             }
@@ -283,27 +299,29 @@ export const CreatePage = () => {
           selectedFiles,
           getSigitFile
         )
-        updateDrawnFiles((draft) => {
+        setDrawnFiles((prev) => {
+          const clone = _.cloneDeep(prev)
           // Existing files are untouched
 
           // Handle removed files
           // Remove in reverse to avoid index issues
-          for (let i = draft.length - 1; i >= 0; i--) {
+          for (let i = clone.length - 1; i >= 0; i--) {
             if (
               !files.some(
-                (f) => f.name === draft[i].name && f.size === draft[i].size
+                (f) => f.name === clone[i].name && f.size === clone[i].size
               )
             ) {
-              draft.splice(i, 1)
+              clone.splice(i, 1)
             }
           }
 
           // Add new files
           files.forEach((f) => {
-            if (!draft.some((d) => d.name === f.name && d.size === f.size)) {
-              draft.push(f)
+            if (!clone.some((d) => d.name === f.name && d.size === f.size)) {
+              clone.push(f)
             }
           })
+          return clone
         })
       }
 
@@ -313,7 +331,52 @@ export const CreatePage = () => {
         setIsParsing(false)
       })
     }
-  }, [selectedFiles, updateDrawnFiles])
+  }, [selectedFiles])
+
+  const [draftEnabled, setDraftEnabled] = useState(true)
+  useEffect(() => {
+    // Only proceed if we have no uploaded files
+    if (uploadedFiles?.length ?? 0) return
+
+    getSigitDraft().then((draft) => {
+      if (draft) {
+        setSelectedFiles(draft.files)
+        setDrawnFiles((prev) => {
+          const clone = _.cloneDeep(prev)
+          clone.splice(0, clone.length, ...draft.files)
+          return clone
+        })
+        setUsers(draft.users)
+        setTitle(draft.title)
+
+        // After loading draft clear it
+        clearSigitDraft()
+      }
+    })
+  }, [uploadedFiles])
+  useEffect(() => {
+    if (draftEnabled) {
+      saveSigitDraft({
+        title,
+        users,
+        lastUpdated: Date.now(),
+        files: drawnFiles
+      }).catch((error) => {
+        if (
+          error instanceof DOMException &&
+          error.name === 'QuotaExceededError'
+        ) {
+          // Disable draft if we hit size error
+          setDraftEnabled(false)
+          console.warn(
+            'Draft functionality disabled temporarily. File size exceeds local storage limit.'
+          )
+          clearSigitDraft()
+        }
+        // Ignore other errors
+      })
+    }
+  }, [draftEnabled, drawnFiles, title, users])
 
   /**
    * Changes the drawing tool
@@ -411,7 +474,7 @@ export const CreatePage = () => {
 
     setUserSearchInput('')
 
-    if (input.startsWith('npub')) {
+    if (input.startsWith('npub1')) {
       return handleAddNpubUser(input)
     }
 
@@ -504,7 +567,7 @@ export const CreatePage = () => {
         })
       })
     })
-    updateDrawnFiles(drawnFilesCopy)
+    setDrawnFiles(drawnFilesCopy)
   }
 
   /**
@@ -926,7 +989,29 @@ export const CreatePage = () => {
           toast.error('Failed to publish notifications')
         })
 
-      const isFirstSigner = signers[0].pubkey === usersPubkey
+      const isFirstSigner =
+        signers.length > 0 && signers[0].pubkey === usersPubkey
+
+      // Don't send notification if creator is next signer
+      if (signers.length > 0 && !isFirstSigner) {
+        // Send DM to the next signer
+        setLoadingSpinnerDesc('Sending DMs')
+        const nextSigner = signers[0].pubkey
+        const createSignatureEvent = parseNostrEvent(meta.createSignature)
+        const { id } = createSignatureEvent
+        try {
+          await sendPrivateDirectMessage(
+            `Sigit created, visit ${window.location.origin}/#/sign/${id}`,
+            npubToHex(nextSigner)!
+          )
+        } catch (error) {
+          if (error instanceof SendDMError) {
+            toast.error(error.message)
+          }
+          console.error(error)
+        }
+      }
+
       if (isFirstSigner) {
         navigate(appPrivateRoutes.sign, { state: { meta } })
       } else {
@@ -940,6 +1025,7 @@ export const CreatePage = () => {
       console.error(error)
     } finally {
       setIsLoading(false)
+      clearSigitDraft()
     }
   }
 
@@ -1017,6 +1103,7 @@ export const CreatePage = () => {
       console.error(error)
     } finally {
       setIsLoading(false)
+      clearSigitDraft()
     }
   }
 
@@ -1034,17 +1121,13 @@ export const CreatePage = () => {
     }
 
     // Seems like it's npub format
-    if (value.startsWith('npub')) {
-      // We will try to convert npub to hex and if it's successfull that means
-      // npub is valid
-      const validHexPubkey = npubToHex(value)
-
-      if (validHexPubkey) {
-        // Arm the manual user npub add after enter is hit, we don't want to trigger search
-        setPastedUserNpubOrNip05(value)
-      } else {
-        disarmAddOnEnter()
-      }
+    if (value.trim().startsWith('npub1')) {
+      setPastedUserNpubOrNip05(value.trim())
+    } else if (value.trim().startsWith('nsec1')) {
+      toast.warn('Oops - never paste your nsec into a website! Key deleted.')
+      if (searchFieldRef.current) searchFieldRef.current.value = ''
+      setUserSearchInput('')
+      return
     } else {
       // Disarm the add user on enter hit, and trigger search after 1 second
       disarmAddOnEnter()
@@ -1204,7 +1287,7 @@ export const CreatePage = () => {
                 {!pastedUserNpubOrNip05 ? (
                   <Button
                     disabled={!userSearchInput || searchUsersLoading}
-                    onClick={() => handleSearchUsers()}
+                    onClick={handleSearchUsers}
                     variant="contained"
                     aria-label="Add"
                     className={styles.counterpartToggleButton}
@@ -1218,7 +1301,7 @@ export const CreatePage = () => {
                 ) : (
                   <Button
                     onClick={() => {
-                      setUserInput(userSearchInput)
+                      setUserInput(userSearchInput.trim())
                     }}
                     variant="contained"
                     aria-label="Add"
@@ -1285,7 +1368,7 @@ export const CreatePage = () => {
             userProfiles={userProfiles}
             selectedTool={selectedTool}
             sigitFiles={drawnFiles}
-            updateSigitFiles={updateDrawnFiles}
+            setSigitFiles={setDrawnFiles}
           />
           {parsingPdf && <LoadingSpinner variant="small" />}
         </StickySideColumns>
diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx
index abd3b4e..44779b4 100644
--- a/src/pages/home/index.tsx
+++ b/src/pages/home/index.tsx
@@ -2,7 +2,7 @@ import { Button, TextField } from '@mui/material'
 import { useCallback, useEffect, useState } from 'react'
 import { useNavigate, useSearchParams } from 'react-router-dom'
 import { toast } from 'react-toastify'
-import { useAppSelector } from '../../hooks'
+import { useAppSelector, useDidMount } from '../../hooks'
 import { appPrivateRoutes } from '../../routes'
 import { Meta } from '../../types'
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
@@ -13,12 +13,15 @@ import { useDropzone } from 'react-dropzone'
 import { Container } from '../../components/Container'
 import styles from './style.module.scss'
 import {
+  clearSigitDraft,
   extractSigitCardDisplayInfo,
+  hasSigitDraft,
   navigateFromZip,
   SigitCardDisplayInfo,
   SigitStatus
 } from '../../utils'
 import { Footer } from '../../components/Footer/Footer'
+import { LocalDraftSigit } from '../../components/DisplaySigit/LocalDraftSigit'
 
 // Unsupported Filter options are commented
 const FILTERS = [
@@ -44,6 +47,12 @@ export const HomePage = () => {
   const [searchParams, setSearchParams] = useSearchParams()
   const q = searchParams.get('q') ?? ''
 
+  const [showDraft, setShowDraft] = useState<boolean>(false)
+  useDidMount(async () => {
+    // Check if draft exists and add link to direct
+    setShowDraft(hasSigitDraft())
+  })
+
   useEffect(() => {
     const searchInput = document.getElementById('q') as HTMLInputElement | null
     if (searchInput) {
@@ -152,7 +161,7 @@ export const HomePage = () => {
           meta={sigits[key]}
         />
       ))
-    } else {
+    } else if (!showDraft) {
       return (
         <div className={styles.noResults}>
           <p>No results</p>
@@ -260,7 +269,17 @@ export const HomePage = () => {
           )}
         </button>
 
-        <div className={styles.submissions}>{renderSubmissions()}</div>
+        <div className={styles.submissions}>
+          {showDraft && (
+            <LocalDraftSigit
+              handleDraftDelete={() => {
+                clearSigitDraft()
+                setShowDraft(false)
+              }}
+            />
+          )}
+          {renderSubmissions()}
+        </div>
       </Container>
       <Footer />
     </div>
diff --git a/src/pages/landing/index.tsx b/src/pages/landing/index.tsx
index 773b923..5d24bdf 100644
--- a/src/pages/landing/index.tsx
+++ b/src/pages/landing/index.tsx
@@ -1,7 +1,5 @@
 import { Box, Button } from '@mui/material'
-import { useEffect } from 'react'
-import { Outlet, useLocation } from 'react-router-dom'
-import { saveVisitedLink } from '../../utils'
+import { Outlet } from 'react-router-dom'
 import { CardComponent } from '../../components/Landing/CardComponent/CardComponent'
 import { Container } from '../../components/Container'
 import styles from './style.module.scss'
@@ -20,13 +18,19 @@ import {
 import { FontAwesomeIconStack } from '../../components/FontAwesomeIconStack'
 import { Footer } from '../../components/Footer/Footer'
 import { launch as launchNostrLoginDialog } from 'nostr-login'
+import { useDidMount } from '../../hooks'
 
 export const LandingPage = () => {
-  const location = useLocation()
-
   const onSignInClick = async () => {
     launchNostrLoginDialog()
   }
+  useDidMount(() => {
+    const isCallback = window.location.hash.startsWith('#/?callbackPath=')
+    // Open nostr login if detect callback
+    if (isCallback) {
+      onSignInClick()
+    }
+  })
 
   const cards = [
     {
@@ -101,10 +105,6 @@ export const LandingPage = () => {
     }
   ]
 
-  useEffect(() => {
-    saveVisitedLink(location.pathname, location.search)
-  }, [location])
-
   return (
     <div className={styles.background}>
       <div
diff --git a/src/pages/profile/index.tsx b/src/pages/profile/index.tsx
index 8e1e8c0..e5b29f6 100644
--- a/src/pages/profile/index.tsx
+++ b/src/pages/profile/index.tsx
@@ -13,7 +13,7 @@ import { Footer } from '../../components/Footer/Footer'
 import { LoadingSpinner } from '../../components/LoadingSpinner'
 import { useAppSelector } from '../../hooks/store'
 
-import { getProfileSettingsRoute } from '../../routes'
+import { appPrivateRoutes } from '../../routes'
 
 import {
   getProfileUsername,
@@ -168,7 +168,7 @@ export const ProfilePage = () => {
               <Box className={styles.right}>
                 {isUsersOwnProfile && (
                   <IconButton
-                    onClick={() => navigate(getProfileSettingsRoute(pubkey))}
+                    onClick={() => navigate(appPrivateRoutes.profileSettings)}
                   >
                     <EditIcon />
                   </IconButton>
diff --git a/src/pages/settings/Settings.tsx b/src/pages/settings/Settings.tsx
index 5acdd9c..4bd9735 100644
--- a/src/pages/settings/Settings.tsx
+++ b/src/pages/settings/Settings.tsx
@@ -1,94 +1,82 @@
 import AccountCircleIcon from '@mui/icons-material/AccountCircle'
-import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos'
-import CachedIcon from '@mui/icons-material/Cached'
 import RouterIcon from '@mui/icons-material/Router'
-import { ListItem, useTheme } from '@mui/material'
-import List from '@mui/material/List'
-import ListItemIcon from '@mui/material/ListItemIcon'
-import ListItemText from '@mui/material/ListItemText'
-import ListSubheader from '@mui/material/ListSubheader'
+import { Button } from '@mui/material'
 import { useAppSelector } from '../../hooks/store'
-import { Link } from 'react-router-dom'
-import { appPrivateRoutes, getProfileSettingsRoute } from '../../routes'
+import { NavLink, Outlet, To } from 'react-router-dom'
+import { appPrivateRoutes } from '../../routes'
 import { Container } from '../../components/Container'
 import { Footer } from '../../components/Footer/Footer'
 import ExtensionIcon from '@mui/icons-material/Extension'
 import { LoginMethod } from '../../store/auth/types'
+import styles from './style.module.scss'
+import { ReactNode } from 'react'
 
-export const SettingsPage = () => {
-  const theme = useTheme()
-  const { usersPubkey, loginMethod } = useAppSelector((state) => state.auth)
-  const listItem = (label: string, disabled = false) => {
-    return (
-      <>
-        <ListItemText
-          primary={label}
+const Item = (to: To, icon: ReactNode, label: string) => {
+  return (
+    <NavLink to={to}>
+      {({ isActive }) => (
+        <Button
+          fullWidth
           sx={{
-            color: theme.palette.text.primary
+            transition: 'ease 0.3s',
+            justifyContent: 'start',
+            gap: '10px',
+            background: 'rgba(76,130,163,0)',
+            color: '#434343',
+            fontWeight: 600,
+            opacity: 0.75,
+            textTransform: 'none',
+            ...(isActive
+              ? {
+                  background: '#447592',
+                  color: 'white'
+                }
+              : {}),
+            '&:hover': {
+              opacity: 0.85,
+              gap: '15px',
+              background: '#5e8eab',
+              color: 'white'
+            }
           }}
-        />
+          variant={'text'}
+        >
+          {icon}
+          {label}
+        </Button>
+      )}
+    </NavLink>
+  )
+}
 
-        {!disabled && (
-          <ArrowForwardIosIcon
-            style={{
-              color: theme.palette.action.active,
-              marginRight: -10
-            }}
-          />
-        )}
-      </>
-    )
-  }
+export const SettingsLayout = () => {
+  const { loginMethod } = useAppSelector((state) => state.auth)
 
   return (
     <>
       <Container>
-        <List
-          sx={{
-            width: '100%',
-            bgcolor: 'background.paper'
-          }}
-          subheader={
-            <ListSubheader
-              sx={{
-                fontSize: '1.5rem',
-                borderBottom: '0.5px solid',
-                paddingBottom: 2,
-                paddingTop: 2,
-                zIndex: 2
-              }}
-            >
-              Settings
-            </ListSubheader>
-          }
-        >
-          <ListItem component={Link} to={getProfileSettingsRoute(usersPubkey!)}>
-            <ListItemIcon>
-              <AccountCircleIcon />
-            </ListItemIcon>
-            {listItem('Profile')}
-          </ListItem>
-          <ListItem component={Link} to={appPrivateRoutes.relays}>
-            <ListItemIcon>
-              <RouterIcon />
-            </ListItemIcon>
-            {listItem('Relays')}
-          </ListItem>
-          <ListItem component={Link} to={appPrivateRoutes.cacheSettings}>
-            <ListItemIcon>
-              <CachedIcon />
-            </ListItemIcon>
-            {listItem('Local Cache')}
-          </ListItem>
-          {loginMethod === LoginMethod.nostrLogin && (
-            <ListItem component={Link} to={appPrivateRoutes.nostrLogin}>
-              <ListItemIcon>
-                <ExtensionIcon />
-              </ListItemIcon>
-              {listItem('Nostr Login')}
-            </ListItem>
-          )}
-        </List>
+        <h2 className={styles.title}>Settings</h2>
+        <div className={styles.main}>
+          <div>
+            <aside className={styles.aside}>
+              {Item(
+                appPrivateRoutes.profileSettings,
+                <AccountCircleIcon />,
+                'Profile'
+              )}
+              {Item(appPrivateRoutes.relays, <RouterIcon />, 'Relays')}
+              {loginMethod === LoginMethod.nostrLogin &&
+                Item(
+                  appPrivateRoutes.nostrLogin,
+                  <ExtensionIcon />,
+                  'Nostr Login'
+                )}
+            </aside>
+          </div>
+          <div className={styles.content}>
+            <Outlet />
+          </div>
+        </div>
       </Container>
       <Footer />
     </>
diff --git a/src/pages/settings/cache/index.tsx b/src/pages/settings/cache/index.tsx
deleted file mode 100644
index 35cc95e..0000000
--- a/src/pages/settings/cache/index.tsx
+++ /dev/null
@@ -1,102 +0,0 @@
-import ClearIcon from '@mui/icons-material/Clear'
-import InputIcon from '@mui/icons-material/Input'
-import IosShareIcon from '@mui/icons-material/IosShare'
-import {
-  List,
-  ListItemButton,
-  ListItemIcon,
-  ListItemText,
-  ListSubheader,
-  useTheme
-} from '@mui/material'
-import { useState } from 'react'
-import { toast } from 'react-toastify'
-import { localCache } from '../../../services'
-import { LoadingSpinner } from '../../../components/LoadingSpinner'
-import { Container } from '../../../components/Container'
-import { Footer } from '../../../components/Footer/Footer'
-
-export const CacheSettingsPage = () => {
-  const theme = useTheme()
-
-  const [isLoading, setIsLoading] = useState(false)
-  const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('')
-
-  const handleClearData = async () => {
-    setIsLoading(true)
-    setLoadingSpinnerDesc('Clearing cache data')
-    localCache
-      .clearCacheData()
-      .then(() => {
-        toast.success('cleared cached data')
-      })
-      .catch((err) => {
-        console.log('An error occurred in clearing cache data', err)
-        toast.error(err.message || 'An error occurred in clearing cache data')
-      })
-      .finally(() => {
-        setIsLoading(false)
-      })
-  }
-
-  const listItem = (label: string) => {
-    return (
-      <ListItemText
-        primary={label}
-        sx={{
-          color: theme.palette.text.primary
-        }}
-      />
-    )
-  }
-
-  return (
-    <>
-      <Container>
-        {isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />}
-        <List
-          sx={{
-            width: '100%',
-            bgcolor: 'background.paper',
-            marginTop: 2
-          }}
-          subheader={
-            <ListSubheader
-              sx={{
-                fontSize: '1.5rem',
-                borderBottom: '0.5px solid',
-                paddingBottom: 2,
-                paddingTop: 2,
-                zIndex: 2
-              }}
-            >
-              Cache Setting
-            </ListSubheader>
-          }
-        >
-          <ListItemButton disabled>
-            <ListItemIcon>
-              <IosShareIcon />
-            </ListItemIcon>
-            {listItem('Export (coming soon)')}
-          </ListItemButton>
-
-          <ListItemButton disabled>
-            <ListItemIcon>
-              <InputIcon />
-            </ListItemIcon>
-            {listItem('Import (coming soon)')}
-          </ListItemButton>
-
-          <ListItemButton onClick={handleClearData}>
-            <ListItemIcon>
-              <ClearIcon sx={{ color: theme.palette.error.main }} />
-            </ListItemIcon>
-            {listItem('Clear Cache')}
-          </ListItemButton>
-        </List>
-      </Container>
-      <Footer />
-    </>
-  )
-}
diff --git a/src/pages/settings/nostrLogin/index.tsx b/src/pages/settings/nostrLogin/index.tsx
index d2f0d29..31434ac 100644
--- a/src/pages/settings/nostrLogin/index.tsx
+++ b/src/pages/settings/nostrLogin/index.tsx
@@ -3,11 +3,9 @@ import {
   ListItemButton,
   ListItemIcon,
   ListItemText,
-  ListSubheader,
   useTheme
 } from '@mui/material'
 import { launch as launchNostrLoginDialog } from 'nostr-login'
-import { Container } from '../../../components/Container'
 import PeopleIcon from '@mui/icons-material/People'
 import ImportExportIcon from '@mui/icons-material/ImportExport'
 import { useAppSelector } from '../../../hooks/store'
@@ -20,59 +18,39 @@ export const NostrLoginPage = () => {
   )
 
   return (
-    <Container>
-      <List
-        sx={{
-          width: '100%',
-          bgcolor: 'background.paper'
+    <List>
+      <ListItemButton
+        onClick={() => {
+          launchNostrLoginDialog('switch-account')
         }}
-        subheader={
-          <ListSubheader
-            sx={{
-              fontSize: '1.5rem',
-              borderBottom: '0.5px solid',
-              paddingBottom: 2,
-              paddingTop: 2,
-              zIndex: 2
-            }}
-          >
-            Nostr Settings
-          </ListSubheader>
-        }
       >
+        <ListItemIcon>
+          <PeopleIcon />
+        </ListItemIcon>
+        <ListItemText
+          primary={'Nostr Login Accounts'}
+          sx={{
+            color: theme.palette.text.primary
+          }}
+        />
+      </ListItemButton>
+      {nostrLoginAuthMethod === NostrLoginAuthMethod.Local && (
         <ListItemButton
           onClick={() => {
-            launchNostrLoginDialog('switch-account')
+            launchNostrLoginDialog('import')
           }}
         >
           <ListItemIcon>
-            <PeopleIcon />
+            <ImportExportIcon />
           </ListItemIcon>
           <ListItemText
-            primary={'Nostr Login Accounts'}
+            primary={'Import / Export Keys'}
             sx={{
               color: theme.palette.text.primary
             }}
           />
         </ListItemButton>
-        {nostrLoginAuthMethod === NostrLoginAuthMethod.Local && (
-          <ListItemButton
-            onClick={() => {
-              launchNostrLoginDialog('import')
-            }}
-          >
-            <ListItemIcon>
-              <ImportExportIcon />
-            </ListItemIcon>
-            <ListItemText
-              primary={'Import / Export Keys'}
-              sx={{
-                color: theme.palette.text.primary
-              }}
-            />
-          </ListItemButton>
-        )}
-      </List>
-    </Container>
+      )}
+    </List>
   )
 }
diff --git a/src/pages/settings/profile/index.tsx b/src/pages/settings/profile/index.tsx
index 57383a7..5ca9000 100644
--- a/src/pages/settings/profile/index.tsx
+++ b/src/pages/settings/profile/index.tsx
@@ -1,5 +1,4 @@
 import React, { useEffect, useRef, useState } from 'react'
-import { useParams } from 'react-router-dom'
 import { toast } from 'react-toastify'
 
 import { SmartToy } from '@mui/icons-material'
@@ -12,7 +11,6 @@ import {
   InputProps,
   List,
   ListItem,
-  ListSubheader,
   TextField,
   Tooltip
 } from '@mui/material'
@@ -28,8 +26,6 @@ import { useAppDispatch, useAppSelector } from '../../../hooks/store'
 
 import { getRoboHashPicture, unixNow } from '../../../utils'
 
-import { Container } from '../../../components/Container'
-import { Footer } from '../../../components/Footer/Footer'
 import { LoadingSpinner } from '../../../components/LoadingSpinner'
 
 import { setUserProfile as updateUserProfile } from '../../../store/actions'
@@ -41,10 +37,8 @@ import styles from './style.module.scss'
 export const ProfileSettingsPage = () => {
   const dispatch: Dispatch = useAppDispatch()
 
-  const { npub } = useParams()
   const { ndk, findMetadata, publish } = useNDKContext()
 
-  const [pubkey, setPubkey] = useState<string>()
   const [userProfile, setUserProfile] = useState<NDKUserProfile | null>(null)
 
   const userRobotImage = useAppSelector((state) => state.user.robotImage)
@@ -55,27 +49,13 @@ export const ProfileSettingsPage = () => {
   )
 
   const [savingProfileMetadata, setSavingProfileMetadata] = useState(false)
-  const [isUsersOwnProfile, setIsUsersOwnProfile] = useState(false)
   const [isLoading, setIsLoading] = useState(true)
   const [loadingSpinnerDesc] = useState('Fetching metadata')
 
   const robotSet = useRef(1)
 
   useEffect(() => {
-    if (npub) {
-      try {
-        const hexPubkey = nip19.decode(npub).data as string
-        setPubkey(hexPubkey)
-
-        if (hexPubkey === usersPubkey) setIsUsersOwnProfile(true)
-      } catch (error) {
-        toast.error('Error occurred in decoding npub' + error)
-      }
-    }
-  }, [npub, usersPubkey])
-
-  useEffect(() => {
-    if (isUsersOwnProfile && currentUserProfile) {
+    if (usersPubkey && currentUserProfile) {
       setUserProfile(currentUserProfile)
 
       setIsLoading(false)
@@ -83,8 +63,8 @@ export const ProfileSettingsPage = () => {
       return
     }
 
-    if (pubkey) {
-      findMetadata(pubkey)
+    if (usersPubkey) {
+      findMetadata(usersPubkey)
         .then((profile) => {
           setUserProfile(profile)
         })
@@ -95,7 +75,7 @@ export const ProfileSettingsPage = () => {
           setIsLoading(false)
         })
     }
-  }, [ndk, isUsersOwnProfile, currentUserProfile, pubkey, findMetadata])
+  }, [ndk, currentUserProfile, findMetadata, usersPubkey])
 
   const editItem = (
     key: keyof NDKUserProfile,
@@ -113,7 +93,6 @@ export const ProfileSettingsPage = () => {
         multiline={multiline}
         rows={rows}
         className={styles.textField}
-        disabled={!isUsersOwnProfile}
         InputProps={inputProps}
         onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
           const { value } = event.target
@@ -170,7 +149,7 @@ export const ProfileSettingsPage = () => {
       content: serializedProfile,
       created_at: unixNow(),
       kind: kinds.Metadata,
-      pubkey: pubkey!,
+      pubkey: usersPubkey!,
       tags: []
     }
 
@@ -215,7 +194,7 @@ export const ProfileSettingsPage = () => {
     robotSet.current++
     if (robotSet.current > 5) robotSet.current = 1
 
-    const robotAvatarLink = getRoboHashPicture(npub!, robotSet.current)
+    const robotAvatarLink = getRoboHashPicture(usersPubkey!, robotSet.current)
 
     setUserProfile((prev) => ({
       ...prev,
@@ -244,143 +223,106 @@ export const ProfileSettingsPage = () => {
    * @returns robohash image url
    */
   const getProfileImage = (profile: NDKUserProfile) => {
-    if (!isUsersOwnProfile) {
-      return profile.image || getRoboHashPicture(npub!)
-    }
-
     // userRobotImage is used only when visiting own profile
     // while kind 0 picture is not set
-    return profile.image || userRobotImage || getRoboHashPicture(npub!)
+    return profile.image || userRobotImage || getRoboHashPicture(usersPubkey!)
   }
 
   return (
     <>
       {isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />}
-      <Container className={styles.container}>
-        <List
-          sx={{
-            bgcolor: 'background.paper',
-            marginTop: 2
-          }}
-          subheader={
-            <ListSubheader
+      <List>
+        {userProfile && (
+          <div>
+            <ListItem
               sx={{
-                paddingBottom: 1,
-                paddingTop: 1,
-                fontSize: '1.5rem',
-                zIndex: 2
+                marginTop: 1,
+                display: 'flex',
+                flexDirection: 'column'
               }}
-              className={styles.subHeader}
             >
-              Profile Settings
-            </ListSubheader>
-          }
-        >
-          {userProfile && (
-            <div>
-              <ListItem
-                sx={{
-                  marginTop: 1,
-                  display: 'flex',
-                  flexDirection: 'column'
-                }}
-              >
-                {userProfile.banner ? (
-                  <img
-                    className={styles.bannerImg}
-                    src={userProfile.banner}
-                    alt="Banner Image"
-                  />
-                ) : (
-                  <Box className={styles.noBanner}> No banner found </Box>
-                )}
-              </ListItem>
-
-              {editItem('banner', 'Banner URL', undefined, undefined)}
-
-              <ListItem
-                sx={{
-                  marginTop: 1,
-                  display: 'flex',
-                  flexDirection: 'column'
-                }}
-              >
+              {userProfile.banner ? (
                 <img
-                  onError={(event: React.SyntheticEvent<HTMLImageElement>) => {
-                    event.currentTarget.src = getRoboHashPicture(npub!)
-                  }}
-                  className={styles.img}
-                  src={getProfileImage(userProfile)}
-                  alt="Profile Image"
+                  className={styles.bannerImg}
+                  src={userProfile.banner}
+                  alt="Banner Image"
                 />
-              </ListItem>
-
-              {editItem('image', 'Picture URL', undefined, undefined, {
-                endAdornment: isUsersOwnProfile ? robohashButton() : undefined
-              })}
-
-              {editItem('name', 'Username')}
-              {editItem('displayName', 'Display Name')}
-              {editItem('nip05', 'Nostr Address (nip05)')}
-              {editItem('lud16', 'Lightning Address (lud16)')}
-              {editItem('about', 'About', true, 4)}
-              {editItem('website', 'Website')}
-              {isUsersOwnProfile && (
-                <>
-                  {usersPubkey &&
-                    copyItem(nip19.npubEncode(usersPubkey), 'Public Key')}
-
-                  {loginMethod === LoginMethod.privateKey &&
-                    keys &&
-                    keys.private &&
-                    copyItem(
-                      '••••••••••••••••••••••••••••••••••••••••••••••••••',
-                      'Private Key',
-                      keys.private
-                    )}
-                </>
+              ) : (
+                <Box className={styles.noBanner}> No banner found </Box>
               )}
-              {isUsersOwnProfile && (
-                <>
-                  {loginMethod === LoginMethod.nostrLogin &&
-                    nostrLoginAuthMethod === NostrLoginAuthMethod.Local && (
-                      <ListItem
-                        sx={{ marginTop: 1 }}
-                        onClick={() => {
-                          launchNostrLoginDialog('import')
-                        }}
-                      >
-                        <TextField
-                          label="Private Key (nostr-login)"
-                          defaultValue="••••••••••••••••••••••••••••••••••••••••••••••••••"
-                          size="small"
-                          className={styles.textField}
-                          disabled
-                          type={'password'}
-                          InputProps={{
-                            endAdornment: (
-                              <LaunchIcon className={styles.copyItem} />
-                            )
-                          }}
-                        />
-                      </ListItem>
-                    )}
-                </>
+            </ListItem>
+
+            {editItem('banner', 'Banner URL', undefined, undefined)}
+
+            <ListItem
+              sx={{
+                marginTop: 1,
+                display: 'flex',
+                flexDirection: 'column'
+              }}
+            >
+              <img
+                onError={(event: React.SyntheticEvent<HTMLImageElement>) => {
+                  event.currentTarget.src = getRoboHashPicture(usersPubkey!)
+                }}
+                className={styles.img}
+                src={getProfileImage(userProfile)}
+                alt="Profile Image"
+              />
+            </ListItem>
+
+            {editItem('image', 'Picture URL', undefined, undefined, {
+              endAdornment: robohashButton()
+            })}
+
+            {editItem('name', 'Username')}
+            {editItem('displayName', 'Display Name')}
+            {editItem('nip05', 'Nostr Address (nip05)')}
+            {editItem('lud16', 'Lightning Address (lud16)')}
+            {editItem('about', 'About', true, 4)}
+            {editItem('website', 'Website')}
+            {usersPubkey &&
+              copyItem(nip19.npubEncode(usersPubkey), 'Public Key')}
+            {loginMethod === LoginMethod.privateKey &&
+              keys &&
+              keys.private &&
+              copyItem(
+                '••••••••••••••••••••••••••••••••••••••••••••••••••',
+                'Private Key',
+                keys.private
               )}
-            </div>
-          )}
-        </List>
-        {isUsersOwnProfile && (
-          <LoadingButton
-            loading={savingProfileMetadata}
-            variant="contained"
-            onClick={handleSaveMetadata}
-          >
-            SAVE
-          </LoadingButton>
+            {loginMethod === LoginMethod.nostrLogin &&
+              nostrLoginAuthMethod === NostrLoginAuthMethod.Local && (
+                <ListItem
+                  sx={{ marginTop: 1 }}
+                  onClick={() => {
+                    launchNostrLoginDialog('import')
+                  }}
+                >
+                  <TextField
+                    label="Private Key (nostr-login)"
+                    defaultValue="••••••••••••••••••••••••••••••••••••••••••••••••••"
+                    size="small"
+                    className={styles.textField}
+                    disabled
+                    type={'password'}
+                    InputProps={{
+                      endAdornment: <LaunchIcon className={styles.copyItem} />
+                    }}
+                  />
+                </ListItem>
+              )}
+          </div>
         )}
-      </Container>
-      <Footer />
+      </List>
+      <LoadingButton
+        sx={{ maxWidth: '300px', alignSelf: 'center', width: '100%' }}
+        loading={savingProfileMetadata}
+        variant="contained"
+        onClick={handleSaveMetadata}
+      >
+        PUBLISH CHANGES
+      </LoadingButton>
     </>
   )
 }
diff --git a/src/pages/settings/profile/style.module.scss b/src/pages/settings/profile/style.module.scss
index 672e59c..6cdc029 100644
--- a/src/pages/settings/profile/style.module.scss
+++ b/src/pages/settings/profile/style.module.scss
@@ -1,9 +1,3 @@
-.container {
-  display: flex;
-  flex-direction: column;
-  gap: 25px;
-}
-
 .textField {
   width: 100%;
 }
diff --git a/src/pages/settings/relays/index.tsx b/src/pages/settings/relays/index.tsx
index c0542c5..9590695 100644
--- a/src/pages/settings/relays/index.tsx
+++ b/src/pages/settings/relays/index.tsx
@@ -12,7 +12,6 @@ import ListItemText from '@mui/material/ListItemText'
 import Switch from '@mui/material/Switch'
 import { useEffect, useState } from 'react'
 import { toast } from 'react-toastify'
-import { Container } from '../../../components/Container'
 import {
   useAppDispatch,
   useAppSelector,
@@ -32,7 +31,6 @@ import {
   timeout
 } from '../../../utils'
 import styles from './style.module.scss'
-import { Footer } from '../../../components/Footer/Footer'
 import {
   getRelayListForUser,
   NDKRelayList,
@@ -246,7 +244,7 @@ export const RelaysPage = () => {
   }
 
   return (
-    <Container className={styles.container}>
+    <>
       <Box className={styles.relayAddContainer}>
         <TextField
           label="Add new relay"
@@ -291,8 +289,7 @@ export const RelaysPage = () => {
           ))}
         </Box>
       )}
-      <Footer />
-    </Container>
+    </>
   )
 }
 
diff --git a/src/pages/settings/relays/style.module.scss b/src/pages/settings/relays/style.module.scss
index 3db7760..df7eb31 100644
--- a/src/pages/settings/relays/style.module.scss
+++ b/src/pages/settings/relays/style.module.scss
@@ -1,107 +1,103 @@
 @import '../../../styles/colors.scss';
 
-.container {
-  color: $text-color;
+.relayURItextfield {
+  width: 100%;
+}
 
-  .relayURItextfield {
-    width: 100%;
+.relayAddContainer {
+  display: flex;
+  flex-direction: row;
+  gap: 10px;
+  width: 100%;
+  align-items: start;
+}
+
+.sectionIcon {
+  font-size: 30px;
+}
+
+.sectionTitle {
+  margin-top: 35px;
+  margin-bottom: 10px;
+  display: flex;
+  flex-direction: row;
+  gap: 5px;
+  font-size: 1.5rem;
+  line-height: 2rem;
+  font-weight: 600;
+}
+
+.relaysContainer {
+  display: flex;
+  flex-direction: column;
+  gap: 15px;
+}
+
+.relay {
+  border: 1px solid rgba(0, 0, 0, 0.12);
+  border-radius: 4px;
+
+  .relayDivider {
+    margin-left: 10px;
+    margin-right: 10px;
   }
 
-  .relayAddContainer {
+  .leaveRelayContainer {
     display: flex;
     flex-direction: row;
     gap: 10px;
-    width: 100%;
-    align-items: start;
+    cursor: pointer;
   }
 
-  .sectionIcon {
-    font-size: 30px;
+  .showInfo {
+    cursor: pointer;
   }
 
-  .sectionTitle {
-    margin-top: 35px;
-    margin-bottom: 10px;
+  .showInfoIcon {
+    margin-right: 3px;
+    margin-bottom: auto;
+    vertical-align: middle;
+  }
+
+  .relayInfoContainer {
     display: flex;
-    flex-direction: row;
+    flex-direction: column;
     gap: 5px;
-    font-size: 1.5rem;
-    line-height: 2rem;
+    text-wrap: wrap;
+  }
+
+  .relayInfoTitle {
     font-weight: 600;
   }
 
-  .relaysContainer {
-    display: flex;
-    flex-direction: column;
-    gap: 15px;
+  .relayInfoSubTitle {
+    font-weight: 500;
   }
 
-  .relay {
-    border: 1px solid rgba(0, 0, 0, 0.12);
-    border-radius: 4px;
-
-    .relayDivider {
-      margin-left: 10px;
-      margin-right: 10px;
-    }
-
-    .leaveRelayContainer {
-      display: flex;
-      flex-direction: row;
-      gap: 10px;
-      cursor: pointer;
-    }
-
-    .showInfo {
-      cursor: pointer;
-    }
-
-    .showInfoIcon {
-      margin-right: 3px;
-      margin-bottom: auto;
-      vertical-align: middle;
-    }
-
-    .relayInfoContainer {
-      display: flex;
-      flex-direction: column;
-      gap: 5px;
-      text-wrap: wrap;
-    }
-
-    .relayInfoTitle {
-      font-weight: 600;
-    }
-
-    .relayInfoSubTitle {
-      font-weight: 500;
-    }
-
-    .copyItem {
-      margin-left: 10px;
-      color: #34495e;
-      vertical-align: bottom;
-      cursor: pointer;
-    }
-
-    .connectionStatus {
-      border-radius: 9999px;
-      width: 10px;
-      height: 10px;
-      margin-right: 5px;
-      margin-top: 2px;
-    }
-
-    .connectionStatusConnected {
-      background-color: $relay-status-connected;
-    }
-
-    .connectionStatusNotConnected {
-      background-color: $relay-status-notconnected;
-    }
-
-    .connectionStatusUnknown {
-      background-color: $input-text-color;
-    }
+  .copyItem {
+    margin-left: 10px;
+    color: #34495e;
+    vertical-align: bottom;
+    cursor: pointer;
   }
-}
+
+  .connectionStatus {
+    border-radius: 9999px;
+    width: 10px;
+    height: 10px;
+    margin-right: 5px;
+    margin-top: 2px;
+  }
+
+  .connectionStatusConnected {
+    background-color: $relay-status-connected;
+  }
+
+  .connectionStatusNotConnected {
+    background-color: $relay-status-notconnected;
+  }
+
+  .connectionStatusUnknown {
+    background-color: $input-text-color;
+  }
+}
\ No newline at end of file
diff --git a/src/pages/settings/style.module.scss b/src/pages/settings/style.module.scss
new file mode 100644
index 0000000..f2d45ef
--- /dev/null
+++ b/src/pages/settings/style.module.scss
@@ -0,0 +1,43 @@
+.title {
+    margin: 0 0 15px 0;
+}
+
+.main {
+    width: 100%;
+    display: grid;
+    grid-template-columns: 0.4fr 1.6fr;
+    position: relative;
+    grid-gap: 25px;
+
+    >* {
+        width: 100%;
+        display: flex;
+        flex-direction: column;
+        grid-gap: 25px;
+    }
+}
+
+.aside {
+    width: 100%;
+    background: white;
+    padding: 15px;
+    border-radius: 5px;
+    box-shadow: 0 0 4px 0 rgb(0, 0, 0, 0.1);
+    display: flex;
+    flex-direction: column;
+    grid-gap: 15px;
+
+    position: sticky;
+    top: 15px;
+}
+
+.content {
+    width: 100%;
+    background: white;
+    padding: 15px;
+    border-radius: 5px;
+    box-shadow: 0 0 4px 0 rgb(0, 0, 0, 0.1);
+    display: flex;
+    flex-direction: column;
+    grid-gap: 15px;
+}
\ No newline at end of file
diff --git a/src/pages/sign/index.tsx b/src/pages/sign/index.tsx
index 07ffd4d..a1a3039 100644
--- a/src/pages/sign/index.tsx
+++ b/src/pages/sign/index.tsx
@@ -28,7 +28,8 @@ import {
   signEventForMetaFile,
   unixNow,
   updateMarks,
-  uploadMetaToFileStorage
+  uploadMetaToFileStorage,
+  parseNostrEvent
 } from '../../utils'
 import { CurrentUserMark, Mark } from '../../types/mark.ts'
 import PdfMarking from '../../components/PDFView/PdfMarking.tsx'
@@ -36,12 +37,14 @@ import { convertToSigitFile, SigitFile } from '../../utils/file.ts'
 import { generateTimestamp } from '../../utils/opentimestamps.ts'
 import { MARK_TYPE_CONFIG } from '../../components/MarkTypeStrategy/MarkStrategy.tsx'
 import { useNDK } from '../../hooks/useNDK.ts'
+import { SendDMError } from '../../types/errors/SendDMError.ts'
 
 export const SignPage = () => {
   const navigate = useNavigate()
   const location = useLocation()
   const params = useParams()
-  const { updateUsersAppData, sendNotification } = useNDK()
+  const { updateUsersAppData, sendNotification, sendPrivateDirectMessage } =
+    useNDK()
 
   const usersAppData = useAppSelector((state) => state.userAppData)
 
@@ -602,6 +605,66 @@ export const SignPage = () => {
         toast.error('Failed to publish notifications')
       })
 
+    // Send DMs
+    setLoadingSpinnerDesc('Sending DMs')
+    const createSignatureEvent = parseNostrEvent(meta.createSignature)
+    const { id } = createSignatureEvent
+
+    if (isLastSigner) {
+      // Final sign sends to everyone (creator, signers, viewers - /verify)
+      const areSent: boolean[] = Array(users.length).fill(false)
+      for (let i = 0; i < users.length; i++) {
+        try {
+          areSent[i] = await sendPrivateDirectMessage(
+            `Sigit completed, visit ${window.location.origin}/#/verify/${id}`,
+            npubToHex(users[i])!
+          )
+        } catch (error) {
+          if (error instanceof SendDMError) {
+            toast.error(error.message)
+          }
+          console.error(error)
+        }
+      }
+
+      if (areSent.some((r) => r)) {
+        toast.success(
+          `DMs sent ${areSent.filter((r) => r).length}/${users.length}`
+        )
+      }
+    } else {
+      // Notify the creator and
+      // the next signer (/sign).
+      try {
+        await sendPrivateDirectMessage(
+          `Sigit signed by ${usersNpub}, visit ${window.location.origin}/#/sign/${id}`,
+          npubToHex(submittedBy!)!
+        )
+      } catch (error) {
+        if (error instanceof SendDMError) {
+          toast.error(error.message)
+        }
+        console.error(error)
+      }
+
+      // No need to notify creator twice, skipping
+      const currentSignerIndex = signers.indexOf(usersNpub)
+      const nextSigner = npubToHex(signers[currentSignerIndex + 1])
+      if (nextSigner !== submittedBy) {
+        try {
+          await sendPrivateDirectMessage(
+            `You're the next signer, visit ${window.location.origin}/#/sign/${id}`,
+            nextSigner!
+          )
+        } catch (error) {
+          if (error instanceof SendDMError) {
+            toast.error(error.message)
+          }
+          console.error(error)
+        }
+      }
+    }
+
     setIsLoading(false)
   }
 
diff --git a/src/routes/PrivateRoute.tsx b/src/routes/PrivateRoute.tsx
new file mode 100644
index 0000000..410ecea
--- /dev/null
+++ b/src/routes/PrivateRoute.tsx
@@ -0,0 +1,21 @@
+import { Navigate, useLocation } from 'react-router-dom'
+import { useAppSelector } from '../hooks'
+import { appPublicRoutes } from '.'
+
+export function PrivateRoute({ children }: { children: JSX.Element }) {
+  const location = useLocation()
+  const isLoggedIn = useAppSelector((state) => state.auth?.loggedIn)
+  if (!isLoggedIn) {
+    return (
+      <Navigate
+        to={{
+          pathname: appPublicRoutes.landingPage,
+          search: `?callbackPath=${btoa(location.pathname)}`
+        }}
+        replace
+      />
+    )
+  }
+
+  return children
+}
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
index f3580f9..f1bd004 100644
--- a/src/routes/index.tsx
+++ b/src/routes/index.tsx
@@ -4,9 +4,7 @@ export const appPrivateRoutes = {
   homePage: '/',
   create: '/create',
   sign: '/sign',
-  settings: '/settings',
-  profileSettings: '/settings/profile/:npub',
-  cacheSettings: '/settings/cache',
+  profileSettings: '/settings/profile',
   relays: '/settings/relays',
   nostrLogin: '/settings/nostrLogin'
 }
@@ -24,6 +22,3 @@ export const appPublicRoutes = {
 
 export const getProfileRoute = (hexKey: string) =>
   appPublicRoutes.profile.replace(':npub', hexToNpub(hexKey))
-
-export const getProfileSettingsRoute = (hexKey: string) =>
-  appPrivateRoutes.profileSettings.replace(':npub', hexToNpub(hexKey))
diff --git a/src/routes/util.tsx b/src/routes/util.tsx
index 8773b81..e0356dd 100644
--- a/src/routes/util.tsx
+++ b/src/routes/util.tsx
@@ -4,13 +4,13 @@ import { CreatePage } from '../pages/create'
 import { HomePage } from '../pages/home'
 import { LandingPage } from '../pages/landing'
 import { ProfilePage } from '../pages/profile'
-import { CacheSettingsPage } from '../pages/settings/cache'
 import { NostrLoginPage } from '../pages/settings/nostrLogin'
 import { ProfileSettingsPage } from '../pages/settings/profile'
 import { RelaysPage } from '../pages/settings/relays'
-import { SettingsPage } from '../pages/settings/Settings'
+import { SettingsLayout } from '../pages/settings/Settings'
 import { SignPage } from '../pages/sign'
 import { VerifyPage } from '../pages/verify'
+import { PrivateRoute } from './PrivateRoute'
 
 /**
  * Helper type allows for extending react-router-dom's **RouteProps** with generic type
@@ -37,7 +37,7 @@ export function recursiveRouteRenderer<T>(
   return routes.map((route, index) =>
     renderConditionCallbackFn(route) ? (
       <Route
-        key={`${route.path}${index}`}
+        key={route.path ? `${route.path}${index}` : index}
         path={route.path}
         element={route.element}
       >
@@ -67,37 +67,50 @@ export const publicRoutes: PublicRouteProps[] = [
   }
 ]
 
-export const privateRoutes = [
+export const privateRoutes: CustomRouteProps<unknown>[] = [
   {
     path: appPrivateRoutes.homePage,
-    element: <HomePage />
+    element: (
+      <PrivateRoute>
+        <HomePage />
+      </PrivateRoute>
+    )
   },
   {
     path: appPrivateRoutes.create,
-    element: <CreatePage />
+    element: (
+      <PrivateRoute>
+        <CreatePage />
+      </PrivateRoute>
+    )
   },
   {
     path: `${appPrivateRoutes.sign}/:id?`,
-    element: <SignPage />
+    element: (
+      <PrivateRoute>
+        <SignPage />
+      </PrivateRoute>
+    )
   },
   {
-    path: appPrivateRoutes.settings,
-    element: <SettingsPage />
-  },
-  {
-    path: appPrivateRoutes.profileSettings,
-    element: <ProfileSettingsPage />
-  },
-  {
-    path: appPrivateRoutes.cacheSettings,
-    element: <CacheSettingsPage />
-  },
-  {
-    path: appPrivateRoutes.relays,
-    element: <RelaysPage />
-  },
-  {
-    path: appPrivateRoutes.nostrLogin,
-    element: <NostrLoginPage />
+    element: (
+      <PrivateRoute>
+        <SettingsLayout />
+      </PrivateRoute>
+    ),
+    children: [
+      {
+        path: appPrivateRoutes.profileSettings,
+        element: <ProfileSettingsPage />
+      },
+      {
+        path: appPrivateRoutes.relays,
+        element: <RelaysPage />
+      },
+      {
+        path: appPrivateRoutes.nostrLogin,
+        element: <NostrLoginPage />
+      }
+    ]
   }
 ]
diff --git a/src/services/cache/index.ts b/src/services/cache/index.ts
deleted file mode 100644
index 957e45b..0000000
--- a/src/services/cache/index.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { IDBPDatabase, openDB } from 'idb'
-import { Event } from 'nostr-tools'
-import { CachedEvent } from '../../types'
-import { SchemaV2 } from './schema'
-
-class LocalCache {
-  // Static property to hold the single instance of LocalCache
-  private static instance: LocalCache | null = null
-  private db!: IDBPDatabase<SchemaV2>
-
-  // Private constructor to prevent direct instantiation
-  private constructor() {}
-
-  // Method to initialize the database
-  private async init() {
-    this.db = await openDB<SchemaV2>('sigit-cache', 2, {
-      upgrade(db, oldVersion) {
-        if (oldVersion < 1) {
-          db.createObjectStore('userMetadata', { keyPath: 'event.pubkey' })
-        }
-
-        if (oldVersion < 2) {
-          const v6 = db as unknown as IDBPDatabase<SchemaV2>
-
-          v6.createObjectStore('userRelayListMetadata', {
-            keyPath: 'event.pubkey'
-          })
-        }
-      }
-    })
-  }
-
-  // Static method to get the single instance of LocalCache
-  public static async getInstance(): Promise<LocalCache> {
-    // If the instance doesn't exist, create it
-    if (!LocalCache.instance) {
-      LocalCache.instance = new LocalCache()
-      await LocalCache.instance.init()
-    }
-    // Return the single instance of LocalCache
-    return LocalCache.instance
-  }
-
-  // Method to add user metadata
-  public async addUserMetadata(event: Event) {
-    await this.db.put('userMetadata', { event, cachedAt: Date.now() })
-  }
-
-  // Method to get user metadata by key
-  public async getUserMetadata(key: string): Promise<CachedEvent | null> {
-    const data = await this.db.get('userMetadata', key)
-    return data || null
-  }
-
-  // Method to delete user metadata by key
-  public async deleteUserMetadata(key: string) {
-    await this.db.delete('userMetadata', key)
-  }
-
-  public async addUserRelayListMetadata(event: Event) {
-    await this.db.put('userRelayListMetadata', { event, cachedAt: Date.now() })
-  }
-
-  public async getUserRelayListMetadata(
-    key: string
-  ): Promise<CachedEvent | null> {
-    const data = await this.db.get('userRelayListMetadata', key)
-    return data || null
-  }
-
-  public async deleteUserRelayListMetadata(key: string) {
-    await this.db.delete('userRelayListMetadata', key)
-  }
-
-  // Method to clear cache data
-  public async clearCacheData() {
-    // Clear the 'userMetadata' store in the IndexedDB database
-    await this.db.clear('userMetadata')
-
-    // Reload the current page to ensure any cached data is reset
-    window.location.reload()
-  }
-}
-
-// Export the single instance of LocalCache
-export const localCache = await LocalCache.getInstance()
diff --git a/src/services/cache/schema.ts b/src/services/cache/schema.ts
deleted file mode 100644
index bc21956..0000000
--- a/src/services/cache/schema.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { DBSchema } from 'idb'
-import { CachedEvent } from '../../types'
-
-export interface SchemaV1 extends DBSchema {
-  userMetadata: {
-    key: string
-    value: CachedEvent
-  }
-}
-
-export interface SchemaV2 extends SchemaV1 {
-  userRelayListMetadata: {
-    key: string
-    value: CachedEvent
-  }
-}
diff --git a/src/services/index.ts b/src/services/index.ts
index b8d275a..eb0b67f 100644
--- a/src/services/index.ts
+++ b/src/services/index.ts
@@ -1,2 +1 @@
-export * from './cache'
 export * from './signer'
diff --git a/src/types/draft.ts b/src/types/draft.ts
new file mode 100644
index 0000000..23709a7
--- /dev/null
+++ b/src/types/draft.ts
@@ -0,0 +1,21 @@
+import { SigitFile } from '../utils/file'
+import { User } from './core'
+import { DrawnField } from './drawing'
+
+export interface SigitFileDraft {
+  name: string
+  file: string
+  pages: DrawnField[][]
+}
+export interface SigitDraft {
+  title: string
+  users: User[]
+  files: SigitFile[]
+  lastUpdated: number
+}
+export interface SerializedSigitDraft {
+  title: string
+  lastUpdated: number
+  users: User[]
+  files: SigitFileDraft[]
+}
diff --git a/src/types/errors/SendDMError.ts b/src/types/errors/SendDMError.ts
new file mode 100644
index 0000000..70cc94a
--- /dev/null
+++ b/src/types/errors/SendDMError.ts
@@ -0,0 +1,23 @@
+import { Jsonable } from '.'
+
+export enum SendDMErrorType {
+  'MISSING_RECIEVER' = 'Sending DM failed. Reciever is required.',
+  'ENCRYPTION_FAILED' = 'Sending DM failed. An error occurred in encrypting dm message.',
+  'RELAY_PUBLISH_FAILED' = 'Sending DM failed. Publishing events failed.'
+}
+
+export class SendDMError extends Error {
+  public readonly context?: Jsonable
+
+  constructor(
+    message: string,
+    options: { cause?: Error; context?: Jsonable } = {}
+  ) {
+    const { cause, context } = options
+
+    super(message, { cause })
+    this.name = this.constructor.name
+
+    this.context = context
+  }
+}
diff --git a/src/types/index.ts b/src/types/index.ts
index 5c5b715..40b240b 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -4,3 +4,5 @@ export * from './nostr'
 export * from './relay'
 export * from './zip'
 export * from './event'
+export * from './drawing'
+export * from './draft'
diff --git a/src/utils/draft.ts b/src/utils/draft.ts
new file mode 100644
index 0000000..e9ba239
--- /dev/null
+++ b/src/utils/draft.ts
@@ -0,0 +1,120 @@
+import {
+  DrawnField,
+  SerializedSigitDraft,
+  SigitDraft,
+  SigitFileDraft
+} from '../types'
+import {
+  getMediaType,
+  extractFileExtension,
+  toFile,
+  getSigitFile
+} from './file'
+const DRAFT_KEY = 'sigitDraft'
+let saveSigitDraftTimeout: number | null = null
+const serializeSigitDraft = async (
+  draft: SigitDraft
+): Promise<SerializedSigitDraft> => {
+  const serializedFiles = draft.files.map((file) => {
+    return new Promise<SigitFileDraft>((resolve, reject) => {
+      const reader = new FileReader()
+      reader.onload = () => {
+        const pages = file.pages
+          ? file.pages.map((page) =>
+              page.drawnFields.map(
+                (field) =>
+                  ({
+                    left: field.left,
+                    top: field.top,
+                    width: field.width,
+                    height: field.height,
+                    type: field.type,
+                    counterpart: field.counterpart
+                  }) as DrawnField
+              )
+            )
+          : []
+        resolve({
+          name: file.name,
+          pages: pages,
+          file: reader.result as string
+        })
+      }
+      reader.onerror = (error) => reject(error)
+      reader.readAsDataURL(file)
+    })
+  })
+
+  const serializedFileDraft = await Promise.all(serializedFiles)
+  return {
+    title: draft.title,
+    lastUpdated: draft.lastUpdated,
+    users: [...draft.users],
+    files: serializedFileDraft
+  }
+}
+
+const deserializeSigitDraft = async (
+  serializedDraft: SerializedSigitDraft
+): Promise<SigitDraft> => {
+  const files = await Promise.all(
+    serializedDraft.files.map(async (draft) => {
+      const response = await fetch(draft.file)
+      const arrayBuffer = await response.arrayBuffer()
+      const type = getMediaType(extractFileExtension(draft.name))
+      const file = toFile(arrayBuffer, draft.name, type)
+      const sigitFile = await getSigitFile(file)
+      if (draft.pages) {
+        for (let i = 0; i < draft.pages.length; i++) {
+          const drawnFields = draft.pages[i]
+          if (sigitFile.pages) sigitFile.pages[i].drawnFields = [...drawnFields]
+        }
+      }
+      return sigitFile
+    })
+  )
+
+  return {
+    ...serializedDraft,
+    files: files
+  }
+}
+
+export const saveSigitDraft = (draft: SigitDraft): Promise<void> => {
+  if (saveSigitDraftTimeout) {
+    clearTimeout(saveSigitDraftTimeout)
+  }
+
+  return new Promise((resolve, reject) => {
+    saveSigitDraftTimeout = window.setTimeout(() => {
+      serializeSigitDraft(draft)
+        .then((draftToSave) => {
+          localStorage.setItem(DRAFT_KEY, JSON.stringify(draftToSave))
+          resolve()
+        })
+        .catch((error) => {
+          reject(error)
+        })
+    }, 1000)
+  })
+}
+
+export const hasSigitDraft = () => {
+  return DRAFT_KEY in localStorage
+}
+
+export const getSigitDraft = async () => {
+  const sigitDraft = localStorage.getItem(DRAFT_KEY)
+  if (!sigitDraft) return null
+
+  try {
+    const serializedDraft = JSON.parse(sigitDraft) as SerializedSigitDraft
+    return await deserializeSigitDraft(serializedDraft)
+  } catch {
+    return null
+  }
+}
+
+export const clearSigitDraft = () => {
+  localStorage.removeItem(DRAFT_KEY)
+}
diff --git a/src/utils/index.ts b/src/utils/index.ts
index 274ceab..9c4464a 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -12,3 +12,4 @@ export * from './string'
 export * from './url'
 export * from './utils'
 export * from './zip'
+export * from './draft'
diff --git a/src/utils/localStorage.ts b/src/utils/localStorage.ts
index 472e092..b0eb381 100644
--- a/src/utils/localStorage.ts
+++ b/src/utils/localStorage.ts
@@ -26,30 +26,6 @@ export const clearState = () => {
   localStorage.removeItem('state')
 }
 
-export const saveVisitedLink = (pathname: string, search: string) => {
-  localStorage.setItem(
-    'visitedLink',
-    JSON.stringify({
-      pathname,
-      search
-    })
-  )
-}
-
-export const getVisitedLink = () => {
-  const visitedLink = localStorage.getItem('visitedLink')
-  if (!visitedLink) return null
-
-  try {
-    return JSON.parse(visitedLink) as {
-      pathname: string
-      search: string
-    }
-  } catch {
-    return null
-  }
-}
-
 export const saveAuthToken = (token: string) => {
   localStorage.setItem('authToken', token)
 }
@@ -66,3 +42,47 @@ export const clear = () => {
   clearAuthToken()
   clearState()
 }
+
+export function mergeWithInitialValue<T>(storedValue: T, initialValue: T): T {
+  if (
+    !Array.isArray(storedValue) &&
+    typeof storedValue === 'object' &&
+    storedValue !== null
+  ) {
+    return { ...initialValue, ...storedValue }
+  }
+  return storedValue
+}
+
+export function getLocalStorageItem<T>(key: string, defaultValue: T): string {
+  try {
+    const data = window.localStorage.getItem(key)
+    if (data === null) return JSON.stringify(defaultValue)
+    return data
+  } catch (err) {
+    console.error(`Error while fetching local storage value: `, err)
+    return JSON.stringify(defaultValue)
+  }
+}
+
+export function setLocalStorageItem(key: string, value: string) {
+  try {
+    window.localStorage.setItem(key, value)
+    dispatchLocalStorageEvent(key, value)
+  } catch (err) {
+    console.error(`Error while saving local storage value: `, err)
+  }
+}
+
+export function removeLocalStorageItem(key: string) {
+  try {
+    window.localStorage.removeItem(key)
+    dispatchLocalStorageEvent(key, null)
+  } catch (err) {
+    console.error(`Error while deleting local storage value: `, err)
+  }
+}
+
+function dispatchLocalStorageEvent(key: string, newValue: string | null) {
+  window.dispatchEvent(new StorageEvent('storage', { key, newValue }))
+}
diff --git a/src/utils/mark.ts b/src/utils/mark.ts
index 1868403..37bda6b 100644
--- a/src/utils/mark.ts
+++ b/src/utils/mark.ts
@@ -171,20 +171,17 @@ export const DEFAULT_TOOLBOX: DrawTool[] = [
   {
     identifier: MarkType.FULLNAME,
     icon: faIdCard,
-    label: 'Full Name',
-    isComingSoon: true
+    label: 'Full Name'
   },
   {
     identifier: MarkType.JOBTITLE,
     icon: faBriefcase,
-    label: 'Job Title',
-    isComingSoon: true
+    label: 'Job Title'
   },
   {
     identifier: MarkType.DATETIME,
     icon: faClock,
-    label: 'Date Time',
-    isComingSoon: true
+    label: 'Date Time'
   },
   {
     identifier: MarkType.NUMBER,
diff --git a/src/utils/meta.ts b/src/utils/meta.ts
index 75e1654..fd68541 100644
--- a/src/utils/meta.ts
+++ b/src/utils/meta.ts
@@ -31,7 +31,8 @@ export enum SignStatus {
 
 export enum SigitStatus {
   Partial = 'In-Progress',
-  Complete = 'Completed'
+  Complete = 'Completed',
+  LocalDraft = 'Draft'
 }
 
 export interface SigitCardDisplayInfo {
diff --git a/src/utils/nostr.ts b/src/utils/nostr.ts
index 600bd08..824a967 100644
--- a/src/utils/nostr.ts
+++ b/src/utils/nostr.ts
@@ -6,6 +6,7 @@ import {
   Event,
   EventTemplate,
   UnsignedEvent,
+  VerifiedEvent,
   finalizeEvent,
   generateSecretKey,
   getEventHash,
@@ -214,6 +215,12 @@ export const toUnixTimestamp = (date: number | Date) => {
 export const fromUnixTimestamp = (unix: number) => {
   return unix * 1000
 }
+export const randomTimeUpTo2DaysInThePast = (): number => {
+  const now = Date.now()
+  const twoDaysInMilliseconds = 2 * 24 * 60 * 60 * 1000
+  const randomPastTime = now - Math.floor(Math.random() * twoDaysInMilliseconds)
+  return toUnixTimestamp(randomPastTime)
+}
 
 /**
  * Generate nip44 conversation key
@@ -263,19 +270,21 @@ export const countLeadingZeroes = (hex: string) => {
 
 /**
  * Function to create a wrapped event with PoW
- * @param event Original event to be wrapped
+ * @param event Original event to be wrapped (can be unsigned or verified)
  * @param receiver Public key of the receiver
- * @param difficulty PoW difficulty level (default is 20)
  * @returns
  */
 //
-export const createWrap = (unsignedEvent: UnsignedEvent, receiver: string) => {
+export const createWrap = (
+  event: UnsignedEvent | VerifiedEvent,
+  receiver: string
+) => {
   // Generate a random secret key and its corresponding public key
   const randomKey = generateSecretKey()
   const pubkey = getPublicKey(randomKey)
 
   // Encrypt the event content using nip44 encryption
-  const content = nip44Encrypt(unsignedEvent, randomKey, receiver)
+  const content = nip44Encrypt(event, randomKey, receiver)
 
   // Initialize nonce and leadingZeroes for PoW calculation
   let nonce = 0
@@ -286,11 +295,12 @@ export const createWrap = (unsignedEvent: UnsignedEvent, receiver: string) => {
   // eslint-disable-next-line no-constant-condition
   while (true) {
     // Create an unsigned event with the necessary fields
+    // TODO: kinds.GiftWrap (wrong kind number in nostr-tools 10/11/2024 at v2.7.2)
     const event: UnsignedEvent = {
       kind: 1059, // Event kind
       content, // Encrypted content
       pubkey, // Public key of the creator
-      created_at: unixNow(), // Current timestamp
+      created_at: randomTimeUpTo2DaysInThePast(),
       tags: [
         // Tags including receiver and nonce
         ['p', receiver],
diff --git a/src/utils/relays.ts b/src/utils/relays.ts
index bcb2e98..ef351d9 100644
--- a/src/utils/relays.ts
+++ b/src/utils/relays.ts
@@ -37,7 +37,6 @@ export const getRelayMapFromNDKRelayList = (ndkRelayList: NDKRelayList) => {
 export const getDefaultRelayMap = (): RelayMap => ({
   [SIGIT_RELAY]: { write: true, read: true }
 })
-
 /**
  * Publishes relay map.
  * @param relayMap - relay map.