Remove deprecated Gnosis org functionality

This functionality is deprecated and the dependencies prevent us from
upgrading our stack.

Signed-off-by: Rūdolfs Ošiņš <rudolfs@osins.org>
This commit is contained in:
Rūdolfs Ošiņš
2022-10-11 15:36:01 +02:00
parent 4bac3fcfdc
commit cb12d8eeab
12 changed files with 69 additions and 948 deletions
+48 -138
View File
@@ -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"
-3
View File
@@ -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",
+4 -217
View File
@@ -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
+9 -135
View File
@@ -1,140 +1,22 @@
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 ethers from "ethers";
import * as cache from "@app/cache";
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(
-1
View File
@@ -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";
-224
View File
@@ -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}
+1 -32
View File
@@ -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)",
-16
View File
@@ -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;
+7 -51
View File
@@ -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;
@@ -100,28 +82,6 @@
.
</div>
<div slot="actions">
<Button variant="secondary" on:click={() => dispatch("close")}>
Done
</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
@@ -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>
-7
View File
@@ -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;
-122
View File
@@ -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;
-2
View File
@@ -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",
),