Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Remove deprecated Gnosis org functionality
Rūdolfs Ošiņš committed 3 years ago
commit cb12d8eeab3b5ff4e9ada5c119d9458f00f86cad
parent 4bac3fcfdce5ec79ad4effe306cd07e3ad908317
12 files changed +67 -946
modified package-lock.json
@@ -9,9 +9,6 @@
      "hasInstallScript": true,
      "dependencies": {
        "@ethersproject/abstract-provider": "^5.4.0",
-
        "@gnosis.pm/safe-core-sdk": "^0.3.1",
-
        "@gnosis.pm/safe-core-sdk-types": "^0.1.1",
-
        "@gnosis.pm/safe-service-client": "^0.1.1",
        "@radicle/gray-matter": "4.1.0",
        "@stardazed/streams": "^3.1.0",
        "@types/marked": "^4.0.7",
@@ -879,29 +876,6 @@
        "@ethersproject/strings": "^5.7.0"
      }
    },
-
    "node_modules/@gnosis.pm/safe-core-sdk": {
-
      "version": "0.3.1",
-
      "resolved": "https://registry.npmjs.org/@gnosis.pm/safe-core-sdk/-/safe-core-sdk-0.3.1.tgz",
-
      "integrity": "sha512-L0na+KSAnicO4B9MtzPu90kwThZ2PHd11CHSRzhJ7l4oIOGB4a/KyPohcOzXTO9Vz3yDIELPlbcW5IEasUk6ag==",
-
      "dependencies": {
-
        "@gnosis.pm/safe-core-sdk-types": "^0.1.1",
-
        "ethereumjs-util": "^7.0.10"
-
      }
-
    },
-
    "node_modules/@gnosis.pm/safe-core-sdk-types": {
-
      "version": "0.1.1",
-
      "resolved": "https://registry.npmjs.org/@gnosis.pm/safe-core-sdk-types/-/safe-core-sdk-types-0.1.1.tgz",
-
      "integrity": "sha512-PghXGDaI5Foq37nZGmI90U2OKMeGtxh5KqkDqou9aFHwGVa/nf9HRQPxG9/XUzcyfe9OlKttDlJnR3XnC3dSDw=="
-
    },
-
    "node_modules/@gnosis.pm/safe-service-client": {
-
      "version": "0.1.1",
-
      "resolved": "https://registry.npmjs.org/@gnosis.pm/safe-service-client/-/safe-service-client-0.1.1.tgz",
-
      "integrity": "sha512-7oQxcs1xTYdS+ZxqFPe44zlu7uzF654QNxI8XSMMnQ11sai7jgoMlom0ucRcWLp1cKATYMNA9+yUgPYYmTRgqA==",
-
      "dependencies": {
-
        "@gnosis.pm/safe-core-sdk-types": "^0.1.0",
-
        "axios": "^0.21.1"
-
      }
-
    },
    "node_modules/@humanwhocodes/config-array": {
      "version": "0.10.7",
      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz",
@@ -1124,14 +1098,6 @@
      "integrity": "sha512-pYrtLtOwku/7r1i9AMONsJMVYAtk3hzOfiGNekhtq5tYBGA7unMve8RvUclKLMT3PrihvJqUmzsRGh0RP84hKg==",
      "dev": true
    },
-
    "node_modules/@types/bn.js": {
-
      "version": "5.1.1",
-
      "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz",
-
      "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==",
-
      "dependencies": {
-
        "@types/node": "*"
-
      }
-
    },
    "node_modules/@types/chai": {
      "version": "4.3.3",
      "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz",
@@ -1211,6 +1177,7 @@
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz",
      "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==",
+
      "dev": true,
      "dependencies": {
        "@types/node": "*"
      }
@@ -1238,6 +1205,7 @@
      "version": "4.0.3",
      "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz",
      "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==",
+
      "dev": true,
      "dependencies": {
        "@types/node": "*"
      }
@@ -1859,14 +1827,6 @@
      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
      "dev": true
    },
-
    "node_modules/axios": {
-
      "version": "0.21.4",
-
      "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
-
      "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
-
      "dependencies": {
-
        "follow-redirects": "^1.14.0"
-
      }
-
    },
    "node_modules/balanced-match": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -1876,6 +1836,7 @@
      "version": "3.0.9",
      "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz",
      "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==",
+
      "dev": true,
      "dependencies": {
        "safe-buffer": "^5.0.1"
      }
@@ -1926,7 +1887,8 @@
    "node_modules/blakejs": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz",
-
      "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ=="
+
      "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==",
+
      "dev": true
    },
    "node_modules/blob-util": {
      "version": "2.0.2",
@@ -1975,6 +1937,7 @@
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+
      "dev": true,
      "dependencies": {
        "buffer-xor": "^1.0.3",
        "cipher-base": "^1.0.0",
@@ -1988,6 +1951,7 @@
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
      "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==",
+
      "dev": true,
      "dependencies": {
        "base-x": "^3.0.2"
      }
@@ -1996,6 +1960,7 @@
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
      "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
+
      "dev": true,
      "dependencies": {
        "bs58": "^4.0.0",
        "create-hash": "^1.1.0",
@@ -2042,7 +2007,8 @@
    "node_modules/buffer-xor": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
-
      "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ=="
+
      "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==",
+
      "dev": true
    },
    "node_modules/cachedir": {
      "version": "2.3.0",
@@ -2201,6 +2167,7 @@
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+
      "dev": true,
      "dependencies": {
        "inherits": "^2.0.1",
        "safe-buffer": "^5.0.1"
@@ -2372,6 +2339,7 @@
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+
      "dev": true,
      "dependencies": {
        "cipher-base": "^1.0.1",
        "inherits": "^2.0.1",
@@ -2384,6 +2352,7 @@
      "version": "1.1.7",
      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+
      "dev": true,
      "dependencies": {
        "cipher-base": "^1.0.3",
        "create-hash": "^1.1.0",
@@ -3405,6 +3374,7 @@
      "version": "0.1.3",
      "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
      "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==",
+
      "dev": true,
      "dependencies": {
        "@types/pbkdf2": "^3.0.0",
        "@types/secp256k1": "^4.0.1",
@@ -3463,21 +3433,6 @@
        "rlp": "^2.2.3"
      }
    },
-
    "node_modules/ethereumjs-util": {
-
      "version": "7.1.5",
-
      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz",
-
      "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==",
-
      "dependencies": {
-
        "@types/bn.js": "^5.1.0",
-
        "bn.js": "^5.1.2",
-
        "create-hash": "^1.1.2",
-
        "ethereum-cryptography": "^0.1.3",
-
        "rlp": "^2.2.4"
-
      },
-
      "engines": {
-
        "node": ">=10.0.0"
-
      }
-
    },
    "node_modules/ethers": {
      "version": "5.7.1",
      "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.1.tgz",
@@ -3557,6 +3512,7 @@
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+
      "dev": true,
      "dependencies": {
        "md5.js": "^1.3.4",
        "safe-buffer": "^5.1.1"
@@ -3790,25 +3746,6 @@
      "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
      "dev": true
    },
-
    "node_modules/follow-redirects": {
-
      "version": "1.15.2",
-
      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
-
      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
-
      "funding": [
-
        {
-
          "type": "individual",
-
          "url": "https://github.com/sponsors/RubenVerborgh"
-
        }
-
      ],
-
      "engines": {
-
        "node": ">=4.0"
-
      },
-
      "peerDependenciesMeta": {
-
        "debug": {
-
          "optional": true
-
        }
-
      }
-
    },
    "node_modules/for-each": {
      "version": "0.3.3",
      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -4158,6 +4095,7 @@
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
      "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+
      "dev": true,
      "dependencies": {
        "inherits": "^2.0.4",
        "readable-stream": "^3.6.0",
@@ -5068,6 +5006,7 @@
      "version": "1.3.5",
      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+
      "dev": true,
      "dependencies": {
        "hash-base": "^3.0.0",
        "inherits": "^2.0.1",
@@ -5525,6 +5464,7 @@
      "version": "3.1.2",
      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
      "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
+
      "dev": true,
      "dependencies": {
        "create-hash": "^1.1.2",
        "create-hmac": "^1.1.4",
@@ -5868,6 +5808,7 @@
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+
      "dev": true,
      "dependencies": {
        "hash-base": "^3.0.0",
        "inherits": "^2.0.1"
@@ -5877,6 +5818,7 @@
      "version": "2.2.7",
      "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz",
      "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==",
+
      "dev": true,
      "dependencies": {
        "bn.js": "^5.2.0"
      },
@@ -6012,6 +5954,7 @@
      "version": "4.0.3",
      "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz",
      "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==",
+
      "dev": true,
      "hasInstallScript": true,
      "dependencies": {
        "elliptic": "^6.5.4",
@@ -6064,12 +6007,14 @@
    "node_modules/setimmediate": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-
      "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
+
      "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+
      "dev": true
    },
    "node_modules/sha.js": {
      "version": "2.4.11",
      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+
      "dev": true,
      "dependencies": {
        "inherits": "^2.0.1",
        "safe-buffer": "^5.0.1"
@@ -7630,29 +7575,6 @@
        "@ethersproject/strings": "^5.7.0"
      }
    },
-
    "@gnosis.pm/safe-core-sdk": {
-
      "version": "0.3.1",
-
      "resolved": "https://registry.npmjs.org/@gnosis.pm/safe-core-sdk/-/safe-core-sdk-0.3.1.tgz",
-
      "integrity": "sha512-L0na+KSAnicO4B9MtzPu90kwThZ2PHd11CHSRzhJ7l4oIOGB4a/KyPohcOzXTO9Vz3yDIELPlbcW5IEasUk6ag==",
-
      "requires": {
-
        "@gnosis.pm/safe-core-sdk-types": "^0.1.1",
-
        "ethereumjs-util": "^7.0.10"
-
      }
-
    },
-
    "@gnosis.pm/safe-core-sdk-types": {
-
      "version": "0.1.1",
-
      "resolved": "https://registry.npmjs.org/@gnosis.pm/safe-core-sdk-types/-/safe-core-sdk-types-0.1.1.tgz",
-
      "integrity": "sha512-PghXGDaI5Foq37nZGmI90U2OKMeGtxh5KqkDqou9aFHwGVa/nf9HRQPxG9/XUzcyfe9OlKttDlJnR3XnC3dSDw=="
-
    },
-
    "@gnosis.pm/safe-service-client": {
-
      "version": "0.1.1",
-
      "resolved": "https://registry.npmjs.org/@gnosis.pm/safe-service-client/-/safe-service-client-0.1.1.tgz",
-
      "integrity": "sha512-7oQxcs1xTYdS+ZxqFPe44zlu7uzF654QNxI8XSMMnQ11sai7jgoMlom0ucRcWLp1cKATYMNA9+yUgPYYmTRgqA==",
-
      "requires": {
-
        "@gnosis.pm/safe-core-sdk-types": "^0.1.0",
-
        "axios": "^0.21.1"
-
      }
-
    },
    "@humanwhocodes/config-array": {
      "version": "0.10.7",
      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz",
@@ -7827,14 +7749,6 @@
      "integrity": "sha512-pYrtLtOwku/7r1i9AMONsJMVYAtk3hzOfiGNekhtq5tYBGA7unMve8RvUclKLMT3PrihvJqUmzsRGh0RP84hKg==",
      "dev": true
    },
-
    "@types/bn.js": {
-
      "version": "5.1.1",
-
      "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz",
-
      "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==",
-
      "requires": {
-
        "@types/node": "*"
-
      }
-
    },
    "@types/chai": {
      "version": "4.3.3",
      "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz",
@@ -7914,6 +7828,7 @@
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz",
      "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==",
+
      "dev": true,
      "requires": {
        "@types/node": "*"
      }
@@ -7941,6 +7856,7 @@
      "version": "4.0.3",
      "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz",
      "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==",
+
      "dev": true,
      "requires": {
        "@types/node": "*"
      }
@@ -8395,14 +8311,6 @@
      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
      "dev": true
    },
-
    "axios": {
-
      "version": "0.21.4",
-
      "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
-
      "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
-
      "requires": {
-
        "follow-redirects": "^1.14.0"
-
      }
-
    },
    "balanced-match": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -8412,6 +8320,7 @@
      "version": "3.0.9",
      "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz",
      "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==",
+
      "dev": true,
      "requires": {
        "safe-buffer": "^5.0.1"
      }
@@ -8447,7 +8356,8 @@
    "blakejs": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz",
-
      "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ=="
+
      "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==",
+
      "dev": true
    },
    "blob-util": {
      "version": "2.0.2",
@@ -8493,6 +8403,7 @@
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+
      "dev": true,
      "requires": {
        "buffer-xor": "^1.0.3",
        "cipher-base": "^1.0.0",
@@ -8506,6 +8417,7 @@
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
      "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==",
+
      "dev": true,
      "requires": {
        "base-x": "^3.0.2"
      }
@@ -8514,6 +8426,7 @@
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
      "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
+
      "dev": true,
      "requires": {
        "bs58": "^4.0.0",
        "create-hash": "^1.1.0",
@@ -8543,7 +8456,8 @@
    "buffer-xor": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
-
      "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ=="
+
      "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==",
+
      "dev": true
    },
    "cachedir": {
      "version": "2.3.0",
@@ -8662,6 +8576,7 @@
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+
      "dev": true,
      "requires": {
        "inherits": "^2.0.1",
        "safe-buffer": "^5.0.1"
@@ -8800,6 +8715,7 @@
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+
      "dev": true,
      "requires": {
        "cipher-base": "^1.0.1",
        "inherits": "^2.0.1",
@@ -8812,6 +8728,7 @@
      "version": "1.1.7",
      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+
      "dev": true,
      "requires": {
        "cipher-base": "^1.0.3",
        "create-hash": "^1.1.0",
@@ -9509,6 +9426,7 @@
      "version": "0.1.3",
      "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
      "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==",
+
      "dev": true,
      "requires": {
        "@types/pbkdf2": "^3.0.0",
        "@types/secp256k1": "^4.0.1",
@@ -9569,18 +9487,6 @@
        }
      }
    },
-
    "ethereumjs-util": {
-
      "version": "7.1.5",
-
      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz",
-
      "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==",
-
      "requires": {
-
        "@types/bn.js": "^5.1.0",
-
        "bn.js": "^5.1.2",
-
        "create-hash": "^1.1.2",
-
        "ethereum-cryptography": "^0.1.3",
-
        "rlp": "^2.2.4"
-
      }
-
    },
    "ethers": {
      "version": "5.7.1",
      "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.1.tgz",
@@ -9643,6 +9549,7 @@
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+
      "dev": true,
      "requires": {
        "md5.js": "^1.3.4",
        "safe-buffer": "^5.1.1"
@@ -9827,11 +9734,6 @@
      "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
      "dev": true
    },
-
    "follow-redirects": {
-
      "version": "1.15.2",
-
      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
-
      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
-
    },
    "for-each": {
      "version": "0.3.3",
      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -10084,6 +9986,7 @@
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
      "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+
      "dev": true,
      "requires": {
        "inherits": "^2.0.4",
        "readable-stream": "^3.6.0",
@@ -10733,6 +10636,7 @@
      "version": "1.3.5",
      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+
      "dev": true,
      "requires": {
        "hash-base": "^3.0.0",
        "inherits": "^2.0.1",
@@ -11071,6 +10975,7 @@
      "version": "3.1.2",
      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
      "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
+
      "dev": true,
      "requires": {
        "create-hash": "^1.1.2",
        "create-hmac": "^1.1.4",
@@ -11308,6 +11213,7 @@
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+
      "dev": true,
      "requires": {
        "hash-base": "^3.0.0",
        "inherits": "^2.0.1"
@@ -11317,6 +11223,7 @@
      "version": "2.2.7",
      "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz",
      "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==",
+
      "dev": true,
      "requires": {
        "bn.js": "^5.2.0"
      }
@@ -11408,6 +11315,7 @@
      "version": "4.0.3",
      "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz",
      "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==",
+
      "dev": true,
      "requires": {
        "elliptic": "^6.5.4",
        "node-addon-api": "^2.0.0",
@@ -11446,12 +11354,14 @@
    "setimmediate": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-
      "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
+
      "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+
      "dev": true
    },
    "sha.js": {
      "version": "2.4.11",
      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+
      "dev": true,
      "requires": {
        "inherits": "^2.0.1",
        "safe-buffer": "^5.0.1"
modified package.json
@@ -38,9 +38,6 @@
  },
  "dependencies": {
    "@ethersproject/abstract-provider": "^5.4.0",
-
    "@gnosis.pm/safe-core-sdk": "^0.3.1",
-
    "@gnosis.pm/safe-core-sdk-types": "^0.1.1",
-
    "@gnosis.pm/safe-service-client": "^0.1.1",
    "@radicle/gray-matter": "4.1.0",
    "@stardazed/streams": "^3.1.0",
    "@types/marked": "^4.0.7",
modified src/Profile.svelte
@@ -8,14 +8,10 @@
  import Icon from "@app/Icon.svelte";
  import SetName from "@app/ens/SetName.svelte";
  import SeedAddress from "@app/SeedAddress.svelte";
-
  import TransferOwnership from "@app/components/TransferOwnership.svelte";
-
  import Link from "@app/Link.svelte";
-
  import { getBalance, Profile, ProfileType } from "@app/profile";
+
  import { Profile, ProfileType } from "@app/profile";
  import Loading from "@app/Loading.svelte";
  import * as utils from "@app/utils";
  import { session } from "@app/session";
-
  import { Org } from "@app/base/orgs/Org";
-
  import Message from "@app/Message.svelte";
  import ErrorModal from "@app/ErrorModal.svelte";
  import { User } from "@app/base/users/User";
  import Projects from "@app/base/seeds/View/Projects.svelte";
@@ -36,11 +32,6 @@
    setNameForm = SetName;
  };

-
  let transferOwnerForm: typeof SvelteComponent | null = null;
-
  const transferOwnership = () => {
-
    transferOwnerForm = TransferOwnership;
-
  };
-

  const getProjectsAndStats = async (
    seed: Seed,
    id?: string,
@@ -53,51 +44,9 @@
    return { stats, projects };
  };

-
  $: account = $session && $session.address;
-
  $: isOwner = (org: Org): boolean =>
-
    $session ? utils.isAddressEqual(org.owner, $session.address) : false;
-
  $: getOrgTreasury = async (
-
    org: Org,
-
  ): Promise<Array<utils.Token> | undefined> => {
-
    const addressType = await utils.identifyAddress(org.owner, config);
-
    // We query the org treasury only for Gnosis Safes, to maintain some privacy for EOA org owners.
-
    if (addressType === utils.AddressType.Safe) {
-
      try {
-
        const tokens = await utils.getTokens(org.owner, config);
-
        const balance = await getBalance(org.owner, config);
-

-
        if (!balance.isZero()) {
-
          // To maintain the format we hardcode the ETH specs.
-
          return [
-
            {
-
              balance,
-
              decimals: 18,
-
              logo: "",
-
              name: "Ethereum",
-
              symbol: "ETH",
-
            },
-
            ...tokens,
-
          ];
-
        } else {
-
          return tokens;
-
        }
-
      } catch (e) {
-
        console.error(e);
-
      }
-
    }
-
  };
  $: isUserAuthorized = (address: string): boolean | null => {
    return $session && utils.isAddressEqual(address, $session.address);
  };
-
  $: isOrgAuthorized = async (org: Org): Promise<boolean> => {
-
    if ($session) {
-
      if (isOwner(org)) {
-
        return true;
-
      }
-
      return await org.isMember($session.address, config);
-
    }
-
    return false;
-
  };
</script>

<style>
@@ -161,29 +110,6 @@
    height: 1.6rem;
    align-items: center;
  }
-
  .members {
-
    margin-top: 2rem;
-
    align-items: center;
-
    display: flex;
-
    flex-wrap: wrap;
-
  }
-
  .members.loading {
-
    padding-bottom: 1rem;
-
  }
-
  .members .member {
-
    display: flex;
-
    align-items: center;
-
    margin-right: 2rem;
-
    margin-bottom: 1rem;
-
  }
-
  .members .member:last-child {
-
    margin-right: 0;
-
  }
-
  .members .member-icon {
-
    width: 2rem;
-
    height: 2rem;
-
    margin-right: 1rem;
-
  }
  @media (max-width: 720px) {
    main {
      width: 100%;
@@ -192,9 +118,6 @@
    .fields {
      grid-template-columns: 5rem auto;
    }
-
    .members .member {
-
      margin-right: 1rem;
-
    }
  }
</style>

@@ -284,32 +207,7 @@
        <div class="mobile">
          <Address compact resolve {config} address={profile.org.owner} />
        </div>
-
        <div class="desktop">
-
          {#await account && profile.org.isMember(account, config) then isMember}
-
            {#if isOwner(profile.org) || isMember}
-
              <Button
-
                variant="secondary"
-
                size="small"
-
                on:click={transferOwnership}>
-
                Transfer
-
              </Button>
-
            {/if}
-
          {/await}
-
        </div>
-
        <!-- Org Treasury -->
-
        {#await getOrgTreasury(profile.org) then tokens}
-
          {#if tokens && tokens.length > 0}
-
            <div class="label">Treasury</div>
-
            <div>
-
              {#each tokens as token}
-
                {` ${utils.formatBalance(token.balance, token.decimals)} ${
-
                  token.symbol
-
                } `}
-
              {/each}
-
            </div>
-
            <div class="desktop" />
-
          {/if}
-
        {/await}
+
        <div class="desktop" />
      {/if}
      <!-- Org Name/Profile -->
      <div class="label">Profile</div>
@@ -324,30 +222,7 @@
              <span class="txt-missing">Not set</span>
            {/if}
          </div>
-
          <div class="desktop">
-
            {#await isOrgAuthorized(profile.org)}
-
              <!-- Loading -->
-
            {:then authorized}
-
              {#if authorized}
-
                <Button variant="secondary" size="small" on:click={setName}>
-
                  Set
-
                </Button>
-
              {/if}
-
            {/await}
-
          </div>
        {/if}
-
        <!-- Quorum -->
-
        {#await profile.org.getSafe(config) then safe}
-
          {#if safe}
-
            <div class="label">Quorum</div>
-
            <div>
-
              {safe.threshold}
-
              <span class="faded">of</span>
-
              {safe.owners.length}
-
            </div>
-
            <div class="desktop" />
-
          {/if}
-
        {/await}
      {:else}
        <!-- User Profile -->
        <div>
@@ -360,7 +235,7 @@
          {/if}
        </div>
        <div class="desktop">
-
          {#if isUserAuthorized(profile.address)}
+
          {#if isUserAuthorized(profile.address) && !profile.org}
            <Button variant="secondary" size="small" on:click={setName}>
              Set
            </Button>
@@ -369,89 +244,6 @@
      {/if}
    </div>

-
    {#if profile.org}
-
      {#await profile.org.getMembers(config)}
-
        <Loading center />
-
      {:then members}
-
        {#if members.length > 0}
-
          <!-- We don't need to catch errors here, since it's not defined by user input and defaults to ETH addresses -->
-
          {#await Profile.getMulti(members, config)}
-
            <div class="members loading">
-
              <Loading small />
-
            </div>
-
          {:then members}
-
            <div class="members">
-
              {#each members as profile}
-
                <div class="member">
-
                  <div class="member-icon">
-
                    <Link to="/{profile.address}">
-
                      <Avatar
-
                        source={profile.avatar ?? profile.address}
-
                        title={profile.address} />
-
                    </Link>
-
                  </div>
-
                  <div class="desktop">
-
                    <Address
-
                      address={profile.address}
-
                      compact
-
                      resolve
-
                      noBadge
-
                      noAvatar
-
                      {profile}
-
                      {config} />
-
                  </div>
-
                </div>
-
              {/each}
-
            </div>
-
          {/await}
-
        {/if}
-
      {:catch err}
-
        <Message error>
-
          <span class="txt-bold">Error:</span>
-
          failed to load org members: {err.message}.
-
        </Message>
-
      {/await}
-
    {:else}
-
      {#await Org.getOrgsByMember(profile.address, config)}
-
        <Loading center />
-
      {:then orgs}
-
        {#if orgs.length > 0}
-
          <div class="members">
-
            {#each orgs as org}
-
              <div class="member">
-
                <!-- We don't need to catch errors here, since it's not defined by user input and defaults to ETH addresses -->
-
                {#await Profile.get(org.address, ProfileType.Minimal, config)}
-
                  <Loading small margins />
-
                {:then profile}
-
                  <div class="member-icon">
-
                    <Link to="/{profile.address}">
-
                      <Avatar
-
                        source={profile.avatar ?? profile.address}
-
                        title={profile.address} />
-
                    </Link>
-
                  </div>
-
                  <div class="desktop">
-
                    <Address
-
                      address={profile.address}
-
                      compact
-
                      resolve
-
                      noBadge
-
                      noAvatar
-
                      {profile}
-
                      {config} />
-
                  </div>
-
                {/await}
-
              </div>
-
            {/each}
-
          </div>
-
        {/if}
-
      {:catch err}
-
        <Message error>
-
          <span class="txt-bold">Error:</span>
-
          failed to load orgs: {err.message}.
-
        </Message>
-
      {/await}
-
    {/if}
    {#if profile.seed?.valid}
      <Async fetch={getProjectsAndStats(profile.seed, profile.id)} let:result>
        <Projects
@@ -465,14 +257,9 @@

  <svelte:component
    this={setNameForm}
-
    entity={profile.org ?? new User(profile.address)}
+
    entity={new User(profile.address)}
    {config}
    on:close={() => (setNameForm = null)} />
-
  <svelte:component
-
    this={transferOwnerForm}
-
    org={profile.org}
-
    {config}
-
    on:close={() => (transferOwnerForm = null)} />
{:catch err}
  {#if err instanceof NotFoundError}
    <NotFound
modified src/base/orgs/Org.ts
@@ -1,140 +1,22 @@
+
import type { Config } from "@app/config";
+

import * as ethers from "ethers";
-
import type { TransactionResponse } from "@ethersproject/providers";
-
import { OperationType } from "@gnosis.pm/safe-core-sdk-types";

-
import { assert } from "@app/error";
-
import * as utils from "@app/utils";
import * as cache from "@app/cache";
-
import type { Safe } from "@app/utils";
-
import type { Config } from "@app/config";
+
import * as utils from "@app/utils";
+
import { assert } from "@app/error";

export class Org {
  address: string;
  owner: string;
  name?: string | null;
-
  safe?: Safe | null;

-
  constructor(
-
    address: string,
-
    owner: string,
-
    name?: string | null,
-
    safe?: Safe | null,
-
  ) {
+
  constructor(address: string, owner: string, name?: string | null) {
    assert(ethers.utils.isAddress(address), "address must be valid");

    this.address = address.toLowerCase(); // Don't store address checksum.
    this.owner = owner;
    this.name = name;
-
    this.safe = safe;
-
  }
-

-
  async setName(name: string, config: Config): Promise<TransactionResponse> {
-
    assert(config.signer);
-

-
    const org = new ethers.Contract(
-
      this.address,
-
      config.abi.org,
-
      config.signer,
-
    );
-
    return org.setName(name, config.provider.network.ensAddress, {
-
      gasLimit: 200_000,
-
    });
-
  }
-

-
  async setNameMultisig(name: string, config: Config): Promise<void> {
-
    assert(config.signer);
-
    assert(config.safe.client);
-

-
    const safeAddress = ethers.utils.getAddress(this.owner);
-
    const orgAddress = ethers.utils.getAddress(this.address);
-
    const org = new ethers.Contract(
-
      this.address,
-
      config.abi.org,
-
      config.signer,
-
    );
-
    const unsignedTx = await org.populateTransaction.setName(
-
      name,
-
      config.provider.network.ensAddress,
-
    );
-

-
    const txData = unsignedTx.data;
-
    if (!txData) {
-
      throw new Error(
-
        "Org::setNameMultisig: Could not generate transaction for `setName` call",
-
      );
-
    }
-

-
    const safeTx = {
-
      to: orgAddress,
-
      value: ethers.constants.Zero.toString(),
-
      data: txData,
-
      operation: OperationType.Call,
-
    };
-
    await utils.proposeSafeTransaction(safeTx, safeAddress, config);
-
  }
-

-
  async setOwner(
-
    address: string,
-
    config: Config,
-
  ): Promise<TransactionResponse> {
-
    assert(config.signer);
-

-
    const org = new ethers.Contract(
-
      this.address,
-
      config.abi.org,
-
      config.signer,
-
    );
-
    return org.setOwner(address);
-
  }
-

-
  async setOwnerMultisig(owner: string, config: Config): Promise<void> {
-
    assert(config.signer);
-
    assert(config.safe.client);
-

-
    const safeAddress = ethers.utils.getAddress(this.owner);
-
    const orgAddress = ethers.utils.getAddress(this.address);
-
    const org = new ethers.Contract(
-
      this.address,
-
      config.abi.org,
-
      config.signer,
-
    );
-
    const unsignedTx = await org.populateTransaction.setOwner(owner);
-

-
    const txData = unsignedTx.data;
-
    if (!txData) {
-
      throw new Error(
-
        "Org::setOwnerMultisig: Could not generate transaction for `setOwner` call",
-
      );
-
    }
-

-
    const safeTx = {
-
      to: orgAddress,
-
      value: ethers.constants.Zero.toString(),
-
      data: txData,
-
      operation: OperationType.Call,
-
    };
-
    await utils.proposeSafeTransaction(safeTx, safeAddress, config);
-
  }
-

-
  async getMembers(config: Config): Promise<Array<string>> {
-
    if (this.safe) return this.safe.owners;
-

-
    const safe = await this.getSafe(config);
-
    if (safe) {
-
      return safe.owners;
-
    }
-
    return [];
-
  }
-

-
  async getSafe(config: Config): Promise<Safe | null> {
-
    if (this.safe) return this.safe;
-

-
    return utils.getSafe(this.owner, config);
-
  }
-

-
  async isMember(address: string, config: Config): Promise<boolean> {
-
    const members = await this.getMembers(config);
-
    return members.includes(address.toLowerCase());
  }

  static async get(addressOrName: string, config: Config): Promise<Org | null> {
@@ -143,26 +25,18 @@ export class Org {
    try {
      const [owner, resolved] = await resolveOrgOwner(org);

-
      const safe = await utils.getSafe(owner, config);
      // If what is resolved is not the same as the input, it's because we
      // were given a name.
      if (utils.isAddressEqual(addressOrName, resolved)) {
-
        return new Org(resolved, owner, null, safe);
+
        return new Org(resolved, owner, null);
      } else {
-
        return new Org(resolved, owner, addressOrName, safe);
+
        return new Org(resolved, owner, addressOrName);
      }
    } catch (e) {
      console.error(e);
      return null;
    }
  }
-

-
  static async getOrgsByMember(
-
    _owner: string,
-
    _config: Config,
-
  ): Promise<Org[]> {
-
    return [];
-
  }
}

export const getOrgContract = cache.cached(
modified src/base/registrations/Submit.svelte
@@ -1,6 +1,5 @@
<script lang="ts">
  // TODO: When name is registered, prompt user to edit records.
-
  // TODO: When transfering name, warn about transfering to org.
  import { onMount } from "svelte";
  import { navigate } from "svelte-routing";
  import type { Session } from "@app/session";
deleted src/components/TransferOwnership.svelte
@@ -1,224 +0,0 @@
-
<script lang="ts" strictEvents>
-
  import type { Org } from "@app/base/orgs/Org";
-
  import type { Config } from "@app/config";
-

-
  import { createEventDispatcher } from "svelte";
-

-
  import * as utils from "@app/utils";
-
  import Address from "@app/Address.svelte";
-
  import Button from "@app/Button.svelte";
-
  import Loading from "@app/Loading.svelte";
-
  import Modal from "@app/Modal.svelte";
-
  import TextInput from "@app/TextInput.svelte";
-
  import { formatAddress, isAddress } from "@app/utils";
-

-
  export let org: Org;
-
  export let config: Config;
-

-
  const dispatch = createEventDispatcher<{ close: boolean }>();
-

-
  let state:
-
    | "idle"
-
    // Single sig.
-
    | "signing"
-
    | "pending"
-
    | "success"
-
    // Multi sig.
-
    | "proposing"
-
    | "proposed"
-
    | "failed" = "idle";
-

-
  let newOwner: string = "";
-
  let errorMessage: string | null = null;
-
  let valid: boolean = false;
-
  let validationMessage: string | undefined = undefined;
-

-
  const onSubmit = async () => {
-
    if (!valid) {
-
      return;
-
    }
-

-
    try {
-
      if (org && (await utils.isSafe(org.owner, config))) {
-
        state = "proposing";
-
        await org.setOwnerMultisig(newOwner, config);
-
        state = "proposed";
-
      } else {
-
        state = "signing";
-
        const tx = await org.setOwner(newOwner, config);
-
        state = "pending";
-
        await tx.wait();
-
        state = "success";
-
      }
-
    } catch (error: unknown) {
-
      if (error instanceof Error) {
-
        errorMessage = error.message;
-
      } else {
-
        errorMessage = "Unknown error.";
-
      }
-
      console.error(error);
-
      state = "failed";
-
    }
-
  };
-

-
  function validate(address: string) {
-
    if (address === "") {
-
      return { valid: false };
-
    }
-

-
    if (state !== "idle") {
-
      return { valid: false };
-
    }
-

-
    if (!isAddress(address)) {
-
      return {
-
        valid: false,
-
        validationMessage: "Please enter a valid Ethereum address.",
-
      };
-
    }
-

-
    return { valid: true };
-
  }
-

-
  $: ({ valid, validationMessage } = validate(newOwner));
-
</script>
-

-
<style>
-
  .actions {
-
    gap: 1rem;
-
    display: flex;
-
    justify-content: center;
-
    margin-top: 2rem;
-
  }
-
  .message {
-
    padding-left: 1rem;
-
    padding-top: 1rem;
-
    word-break: break-all;
-
  }
-
</style>
-

-
{#if state === "success" && newOwner}
-
  <Modal floating small>
-
    <div slot="title">✅</div>
-

-
    <div slot="subtitle">
-
      The ownership of <span class="txt-bold">
-
        {formatAddress(org.address)}
-
      </span>
-
      was successfully transfered to
-
      <span class="txt-bold">{newOwner}</span>
-
      .
-
    </div>
-

-
    <div slot="actions">
-
      <Button variant="secondary" on:click={() => dispatch("close")}>
-
        Done
-
      </Button>
-
    </div>
-
  </Modal>
-
{:else if state === "proposed" && org}
-
  <Modal floating>
-
    <div slot="title">🪴</div>
-

-
    <div slot="subtitle">
-
      <p>
-
        The transaction to set the owner of <span class="txt-bold">
-
          {formatAddress(org.address)}
-
        </span>
-
        to
-
        <span class="txt-bold">{newOwner}</span>
-
        was proposed to:
-
      </p>
-
      <p><Address address={org.owner} {config} compact /></p>
-
    </div>
-

-
    <div slot="actions">
-
      <Button variant="secondary" on:click={() => dispatch("close")}>
-
        Done
-
      </Button>
-
    </div>
-
  </Modal>
-
{:else if state === "failed"}
-
  <Modal floating error small>
-
    <div slot="title">
-
      🔑
-
      <div>Transfer ownership</div>
-
    </div>
-

-
    <div slot="subtitle">
-
      <div class="message">
-
        {errorMessage}
-
      </div>
-
    </div>
-

-
    <div slot="actions" class="actions">
-
      <Button
-
        variant="negative"
-
        on:click={() => {
-
          state = "idle";
-
        }}>
-
        Back
-
      </Button>
-
    </div>
-
  </Modal>
-
{:else}
-
  <Modal floating>
-
    <div slot="title">
-
      🔑
-
      <div>Transfer ownership</div>
-
    </div>
-

-
    <div slot="subtitle">
-
      {#if state === "signing"}
-
        Please confirm the transaction in your wallet.
-
      {:else if state === "pending"}
-
        Waiting for transaction to be processed…
-
      {:else if state === "proposing" && org}
-
        Proposal is being submitted to the safe
-
        <span class="txt-bold">{formatAddress(org.owner)}</span>
-
        , please sign the transaction in your wallet.
-
      {:else if state === "idle"}
-
        Transfer the ownership of Org <span class="txt-bold">
-
          {formatAddress(org.address)}
-
        </span>
-
        to a new address.
-
      {/if}
-
    </div>
-

-
    <div slot="body" style="display: flex;justify-content: center;">
-
      {#if state === "idle"}
-
        <div style="position: absolute; text-align: left;">
-
          <div style="width: 31rem;">
-
            <TextInput
-
              autofocus
-
              {valid}
-
              {validationMessage}
-
              on:submit={onSubmit}
-
              disabled={state !== "idle"}
-
              bind:value={newOwner} />
-
          </div>
-
        </div>
-
      {:else if state === "pending" || state === "proposing" || state === "signing"}
-
        <Loading small center />
-
      {/if}
-
    </div>
-

-
    <div slot="actions" class="actions">
-
      {#if state === "signing"}
-
        <Button variant="text" on:click={() => dispatch("close")}>
-
          Cancel
-
        </Button>
-
      {:else if state === "pending"}
-
        <Button variant="text" on:click={() => dispatch("close")}>Close</Button>
-
      {:else}
-
        <Button variant="primary" on:click={onSubmit} disabled={!valid}>
-
          Submit
-
        </Button>
-

-
        <Button variant="text" on:click={() => dispatch("close")}>
-
          Cancel
-
        </Button>
-
      {/if}
-
    </div>
-
  </Modal>
-
{/if}
modified src/config.json
@@ -7,21 +7,6 @@
    "radToken": {
      "address": "0x31c8EAcBFFdD875c74b94b077895Bd78CF1E64A3"
    },
-
    "orgFactory": {
-
      "address": "0xa15bEb4876F20018b6b4A4116B7560c5fcC9336e"
-
    },
-
    "orgs": {
-
      "contractHash": "0x5c34bb0755876de98e801805e6685456eea739ad0abba1cc450a7ee0f2a70b74",
-
      "pinned": [
-
        "alt-clients.radicle.eth",
-
        "community.radicle.eth",
-
        "upstream.radicle.eth",
-
        "gnosisguild.radicle.eth",
-
        "grants.radicle.eth",
-
        "gip-editors.radicle.eth",
-
        "dxdao.radicle.eth"
-
      ]
-
    },
    "users": {
      "pinned": ["cloudhead.radicle.eth"]
    },
@@ -44,13 +29,6 @@
      "address": "0x7b6CbebC5646D996d258dcD4ca1d334B282e9948",
      "faucet": "0x9Aa75397eD632A3060aCb5dE7f96e2457bceED8d"
    },
-
    "orgFactory": {
-
      "address": "0xF3D04e874D07d680e8b26332eEae5b9B1c263121"
-
    },
-
    "orgs": {
-
      "contractHash": "0x5c34bb0755876de98e801805e6685456eea739ad0abba1cc450a7ee0f2a70b74",
-
      "pinned": []
-
    },
    "users": {
      "pinned": []
    },
@@ -177,17 +155,8 @@
      "function setAddr(bytes32 node, address addr)",
      "function setText(bytes32 node, string calldata key, string calldata value)"
    ],
-
    "orgFactory": [
-
      "function createOrg(address) returns (address)",
-
      "function createOrg(address[], uint256) returns (address)",
-
      "event OrgCreated(address, address)"
-
    ],
    "reverseRegistrar": ["function setName(string) returns (bytes32)"],
-
    "org": [
-
      "function owner() view returns (address)",
-
      "function setOwner(address)",
-
      "function setName(string, address) returns (bytes32)"
-
    ],
+
    "org": ["function owner() view returns (address)"],
    "vesting": [
      "function token() view returns (address)",
      "function totalVestingAmount() view returns (uint256)",
modified src/config.ts
@@ -2,7 +2,6 @@ import { get, writable } from "svelte/store";
import type { Writable } from "svelte/store";
import { ethers } from "ethers";
import type { TypedDataSigner } from "@ethersproject/abstract-signer";
-
import SafeServiceClient from "@gnosis.pm/safe-service-client";
import WalletConnect from "@walletconnect/client";
import config from "@app/config.json";
import { WalletConnectSigner } from "./WalletConnectSigner";
@@ -16,11 +15,6 @@ declare global {
  }
}

-
/// Gas limits for various transactions.
-
const gasLimits = {
-
  createOrg: 1_200_000,
-
};
-

export type WalletConnectState =
  | { state: "close" }
  | { state: "open"; uri: string; onClose: any };
@@ -29,13 +23,10 @@ export class Config {
  network: { name: string; chainId: number };
  registrar: { address: string; domain: string };
  radToken: { address: string; faucet: string };
-
  orgFactory: { address: string };
  reverseRegistrar: { address: string };
-
  orgs: { contractHash: string; pinned: string[] };
  users: { pinned: string[] };
  projects: { pinned: { urn: string; name: string; seed: string }[] };
  seeds: { pinned: Record<string, { emoji: string }> };
-
  gasLimits: { createOrg: number };
  provider: ethers.providers.JsonRpcProvider;
  signer: (ethers.Signer & TypedDataSigner) | WalletConnectSigner | null;
  walletConnect: {
@@ -56,7 +47,6 @@ export class Config {
      };
  safe: {
    api?: string;
-
    client?: SafeServiceClient;
    viewer: string | null;
  };
  abi: { [contract: string]: string[] };
@@ -105,17 +95,11 @@ export class Config {
    this.seed = config.radicle.seed;
    this.registrar = cfg.registrar;
    this.radToken = cfg.radToken;
-
    this.orgFactory = cfg.orgFactory;
    this.reverseRegistrar = cfg.reverseRegistrar;
-
    this.orgs = cfg.orgs;
    this.users = cfg.users;
    this.safe = cfg.safe;
-
    this.safe.client = this.safe.api
-
      ? new SafeServiceClient(this.safe.api)
-
      : undefined;
    this.provider = provider;
    this.signer = null;
-
    this.gasLimits = gasLimits;
    this.projects = config.projects;
    this.seeds = config.seeds;
    this.abi = config.abi;
modified src/ens/SetName.svelte
@@ -4,37 +4,25 @@
  import Modal from "@app/Modal.svelte";
  import type { Config } from "@app/config";
  import { formatAddress, isAddressEqual } from "@app/utils";
-
  import { Org } from "@app/base/orgs/Org";
  import type { User } from "@app/base/users/User";
  import ErrorModal from "@app/ErrorModal.svelte";
-
  import Address from "@app/Address.svelte";
-
  import * as utils from "@app/utils";
  import Button from "@app/Button.svelte";
  import TextInput from "@app/TextInput.svelte";
  import Loading from "@app/Loading.svelte";

  const dispatch = createEventDispatcher();

-
  export let entity: Org | User;
+
  export let entity: User;
  export let config: Config;

-
  const org = Org.hasOwnProperty.call(entity, "owner") ? (entity as Org) : null;
-

-
  const label = org ? "org" : "profile";
-

  enum State {
    Idle,
    Checking,

-
    // Single-sig states.
    Signing,
    Pending,
    Success,

-
    // Multi-sig states.
-
    Proposing,
-
    Proposed,
-

    Failed,
    Mismatch,
  }
@@ -54,17 +42,11 @@

    if (resolved && isAddressEqual(resolved, entity.address)) {
      try {
-
        if (org && (await utils.isSafe(org.owner, config))) {
-
          state = State.Proposing;
-
          await org.setNameMultisig(domain, config);
-
          state = State.Proposed;
-
        } else {
-
          state = State.Signing;
-
          const tx = await entity.setName(domain, config);
-
          state = State.Pending;
-
          await tx.wait();
-
          state = State.Success;
-
        }
+
        state = State.Signing;
+
        const tx = await entity.setName(domain, config);
+
        state = State.Pending;
+
        await tx.wait();
+
        state = State.Success;
      } catch (e) {
        console.error(e);
        state = State.Failed;
@@ -106,28 +88,6 @@
      </Button>
    </div>
  </Modal>
-
{:else if state === State.Proposed && org}
-
  <Modal floating>
-
    <div slot="title">🪴</div>
-

-
    <div slot="subtitle">
-
      <p>
-
        The transaction to set the ENS name for <span class="txt-bold">
-
          {formatAddress(entity.address)}
-
        </span>
-
        to
-
        <span class="txt-bold">{name}.{config.registrar.domain}</span>
-
        was proposed to:
-
      </p>
-
      <p><Address address={org.owner} {config} compact /></p>
-
    </div>
-

-
    <div slot="actions">
-
      <Button variant="secondary" on:click={() => dispatch("close")}>
-
        Done
-
      </Button>
-
    </div>
-
  </Modal>
{:else if state === State.Mismatch}
  <ErrorModal floating title="🧣" on:close>
    The name <span class="txt-bold">{name}.{config.registrar.domain}</span>
@@ -161,16 +121,12 @@
        Please confirm the transaction in your wallet.
      {:else if state === State.Pending}
        Waiting for transaction to be processed…
-
      {:else if state === State.Proposing && org}
-
        Proposal is being submitted
-
        <span class="txt-bold">{formatAddress(org.owner)}</span>
-
        , please sign the transaction in your wallet.
      {:else}
        Set an ENS name for <span class="txt-bold">
          {formatAddress(entity.address)}
        </span>
        to associate a profile. ENS profiles provide human-identifiable data to your
-
        {label}, such as a unique name, avatar and URL, and help make your {label}
+
        profile, such as a unique name, avatar and URL, and help make your profile
        more discoverable.
      {/if}
    </div>
deleted src/polyfills/stream.ts
@@ -1,7 +0,0 @@
-
// This shim is used as a stand-in for the node "stream" library, used by
-
// the "keccack" package depended on by @gnosis.pm/safe-core-sdk.
-
import * as streams from "@stardazed/streams";
-

-
// "Transform" is the old name for "TransformStream".
-
export const Transform = streams.TransformStream;
-
export default streams;
modified src/utils.ts
@@ -5,9 +5,6 @@ import { BigNumber } from "ethers";
import multibase from "multibase";
import katex from "katex";
import multihashes from "multihashes";
-
import type { TransactionResult } from "@gnosis.pm/safe-core-sdk";
-
import EthersSafe, { EthersAdapter } from "@gnosis.pm/safe-core-sdk";
-
import type { SafeSignature } from "@gnosis.pm/safe-core-sdk-types";
import type { Config } from "@app/config";
import config from "@app/config.json";
import { assert } from "@app/error";
@@ -422,18 +419,10 @@ export async function identifyAddress(
  address: string,
  config: Config,
): Promise<AddressType> {
-
  const safe = await isSafe(address, config);
-
  if (safe) {
-
    return AddressType.Safe;
-
  }
-

  const code = await getCode(address, config);
  const bytes = ethers.utils.arrayify(code);

  if (bytes.length > 0) {
-
    if (ethers.utils.keccak256(bytes) === config.orgs.contractHash) {
-
      return AddressType.Org;
-
    }
    return AddressType.Contract;
  }
  return AddressType.EOA;
@@ -513,22 +502,6 @@ export async function resolveEnsProfile(
  return null;
}

-
// Check whether a Gnosis Safe exists at an address.
-
export async function isSafe(
-
  _address: string,
-
  _config: Config,
-
): Promise<boolean> {
-
  return false;
-
}
-

-
// Get a Gnosis Safe at an address.
-
export async function getSafe(
-
  _address: string,
-
  _config: Config,
-
): Promise<Safe | null> {
-
  return null;
-
}
-

// Get token balances for an address.
export async function getTokens(
  address: string,
@@ -595,101 +568,6 @@ export function gravatarURL(email: string): string {
  return `https://www.gravatar.com/avatar/${hash}`;
}

-
// Propose a Gnosis Safe multi-sig transaction.
-
export async function proposeSafeTransaction(
-
  safeTx: SafeTransaction,
-
  safeAddress: string,
-
  config: Config,
-
): Promise<void> {
-
  assert(config.signer);
-
  assert(config.safe.client);
-

-
  const ethAdapter = new EthersAdapter({
-
    ethers,
-
    signer: config.signer,
-
  });
-
  const safeSdk = await EthersSafe.create({
-
    ethAdapter,
-
    safeAddress,
-
  });
-
  const estimation = await config.safe.client.estimateSafeTransaction(
-
    safeAddress,
-
    safeTx,
-
  );
-
  const transaction = await safeSdk.createTransaction({
-
    ...safeTx,
-
    safeTxGas: Number(estimation.safeTxGas),
-
  });
-
  const safeTxHash = await safeSdk.getTransactionHash(transaction);
-
  const signature = await safeSdk.signTransactionHash(safeTxHash);
-

-
  await config.safe.client.proposeTransaction(
-
    safeAddress,
-
    transaction.data,
-
    safeTxHash,
-
    signature,
-
  );
-
}
-

-
// Sign a Gnosis Safe multi-sig transaction.
-
export async function signSafeTransaction(
-
  safeAddress: string,
-
  safeTxHash: string,
-
  config: Config,
-
): Promise<SafeSignature> {
-
  assert(config.signer);
-

-
  const ethAdapter = new EthersAdapter({
-
    ethers,
-
    signer: config.signer,
-
  });
-
  const safeSdk = await EthersSafe.create({
-
    ethAdapter,
-
    safeAddress,
-
  });
-
  return await safeSdk.signTransactionHash(safeTxHash);
-
}
-

-
// Execute a Gnosis Safe signed transaction by safeTxHash.
-
export async function executeSignedSafeTransaction(
-
  safeAddress: string,
-
  safeTxHash: string,
-
  config: Config,
-
): Promise<TransactionResult> {
-
  assert(config.signer);
-
  assert(config.safe.client);
-

-
  const ethAdapter = new EthersAdapter({
-
    ethers,
-
    signer: config.signer,
-
  });
-
  const safeSdk = await EthersSafe.create({
-
    ethAdapter,
-
    safeAddress,
-
  });
-

-
  const signedTx = await config.safe.client.getTransaction(safeTxHash);
-

-
  assert(signedTx.data);
-
  assert(signedTx.confirmations);
-

-
  const safeTx = await safeSdk.createTransaction({
-
    ...signedTx,
-
    gasPrice: Number(signedTx.gasPrice),
-
    data: signedTx.data,
-
  });
-

-
  signedTx.confirmations.forEach(confirmation => {
-
    const signature = new EthSignSignature(
-
      confirmation.owner,
-
      confirmation.signature,
-
    );
-
    safeTx.addSignature(signature);
-
  });
-

-
  return await safeSdk.executeTransaction(safeTx);
-
}
-

export class EthSignSignature {
  signer: string;
  data: string;
modified vite.config.ts
@@ -36,8 +36,6 @@ const config: UserConfig = {
    alias: {
      "@public": path.resolve("./public"),
      "@app": path.resolve("./src"),
-
      // Polyfill for Node.js 'stream' library.
-
      stream: path.resolve("./src/polyfills/stream.ts"),
      "typedarray-to-buffer": path.resolve(
        "./src/polyfills/typedarray-to-buffer.js",
      ),