diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 29d5104..b9da5bc 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -3,7 +3,7 @@
-
+
diff --git a/package-lock.json b/package-lock.json
index 4e942dd..670c23b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,14 +20,16 @@
"@solana/wallet-adapter-wallets": "0.15.5",
"@solana/web3.js": "1.43.1",
"@tokr-labs/cap-table": "0.3.0",
- "@tokr-labs/governance": "0.2.0",
+ "@tokr-labs/governance": "0.3.0",
"@tokr-labs/identity-verification": "0.7.0",
"amplitude-js": "8.18.1",
+ "bn.js": "5.2.0",
"boxicons": "2.1.2",
"crypto-browserify": "3.12.0",
+ "random-word-slugs": "0.1.6",
"react": "18.1.0",
"react-dom": "18.1.0",
- "react-icons": "^4.4.0",
+ "react-icons": "4.4.0",
"react-router-dom": "6.3.0",
"react-scripts": "5.0.1",
"recharts": "2.1.10",
@@ -49,6 +51,9 @@
"@types/react-dom": "18.0.5",
"@types/underscore": "1.11.4",
"process": "0.11.10"
+ },
+ "engines": {
+ "node": ">=16"
}
},
"node_modules/@amplitude/analytics-connector": {
@@ -2029,7 +2034,7 @@
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
- "devOptional": true,
+ "dev": true,
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
@@ -2041,7 +2046,7 @@
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
- "devOptional": true,
+ "dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
@@ -5267,10 +5272,11 @@
"integrity": "sha512-QvjkYpiD+dJJraRA8+dGAU4i7aBbb2s0S3jA45TFOvg2VgqvdCDd/3N6CqA8gluk1W91GLoXg5enMUx560QzuA=="
},
"node_modules/@tokr-labs/governance": {
- "version": "0.2.0",
- "resolved": "https://npm.pkg.github.com/download/@tokr-labs/governance/0.2.0/0d56b1583bf0bc76f75d44eb57efbf7cdd86e43684f04520693d1b4badf12ebb",
- "integrity": "sha512-wSBhLI12aHnxwu5Lmfi5qB00PeeDNro74cjcmQq9WHjW7HoXCrgtU1HnKLso1JYDWAsp3dYAs17NYdVdD4I78w==",
+ "version": "0.3.0",
+ "resolved": "https://npm.pkg.github.com/download/@tokr-labs/governance/0.3.0/89bec58861c9af343af745fa495b2cf396f2d1742de0c6de4b15b7eb3a0a19e9",
+ "integrity": "sha512-ql+gGySiFIX1TmTPisZg06exOG55hVklBhHf3tLJEQp5dU9etakBME4AyZ4/LJlc7rasOQgBx65mfA8dkb4oXg==",
"dependencies": {
+ "@solana/spl-token": "0.2.0",
"@solana/web3.js": "1.43.1",
"bignumber.js": "9.0.1",
"bn.js": "5.1.3",
@@ -5557,25 +5563,25 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
"integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
- "devOptional": true
+ "dev": true
},
"node_modules/@tsconfig/node12": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
"integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
- "devOptional": true
+ "dev": true
},
"node_modules/@tsconfig/node14": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
"integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
- "devOptional": true
+ "dev": true
},
"node_modules/@tsconfig/node16": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
- "devOptional": true
+ "dev": true
},
"node_modules/@types/amplitude-js": {
"version": "8.16.0",
@@ -5828,7 +5834,7 @@
"version": "16.11.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.36.tgz",
"integrity": "sha512-FR5QJe+TaoZ2GsMHkjuwoNabr+UrJNRr2HNOo+r/7vhcuntM6Ee/pRPOnRhhL2XE9OOvX9VLEq+BcXl3VjNoWA==",
- "devOptional": true
+ "dev": true
},
"node_modules/@types/parse-json": {
"version": "4.0.0",
@@ -7413,9 +7419,9 @@
"integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w=="
},
"node_modules/bn.js": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
- "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
},
"node_modules/body-parser": {
"version": "1.20.0",
@@ -8307,7 +8313,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
- "devOptional": true
+ "dev": true
},
"node_modules/cross-fetch": {
"version": "3.1.5",
@@ -8761,28 +8767,36 @@
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz",
"integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA=="
},
+ "node_modules/d3-array": {
+ "version": "2.12.1",
+ "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
+ "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
+ "dependencies": {
+ "internmap": "^1.0.0"
+ }
+ },
"node_modules/d3-color": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz",
- "integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
+ "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
},
"node_modules/d3-format": {
- "version": "1.4.5",
- "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz",
- "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz",
+ "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA=="
},
"node_modules/d3-interpolate": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz",
- "integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
+ "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
"dependencies": {
- "d3-color": "1"
+ "d3-color": "1 - 2"
}
},
"node_modules/d3-path": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
- "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz",
+ "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA=="
},
"node_modules/d3-scale": {
"version": "3.3.0",
@@ -8796,15 +8810,15 @@
"d3-time-format": "2 - 3"
}
},
- "node_modules/d3-scale/node_modules/d3-array": {
- "version": "2.12.1",
- "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
- "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
+ "node_modules/d3-shape": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz",
+ "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==",
"dependencies": {
- "internmap": "^1.0.0"
+ "d3-path": "1 - 2"
}
},
- "node_modules/d3-scale/node_modules/d3-time": {
+ "node_modules/d3-time": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
"integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
@@ -8812,17 +8826,12 @@
"d3-array": "2"
}
},
- "node_modules/d3-time": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz",
- "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA=="
- },
"node_modules/d3-time-format": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.3.0.tgz",
- "integrity": "sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz",
+ "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==",
"dependencies": {
- "d3-time": "1"
+ "d3-time": "1 - 2"
}
},
"node_modules/damerau-levenshtein": {
@@ -9109,7 +9118,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
- "devOptional": true,
+ "dev": true,
"engines": {
"node": ">=0.3.1"
}
@@ -14911,7 +14920,7 @@
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
- "devOptional": true
+ "dev": true
},
"node_modules/makeerror": {
"version": "1.0.12",
@@ -17346,6 +17355,11 @@
"performance-now": "^2.1.0"
}
},
+ "node_modules/random-word-slugs": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/random-word-slugs/-/random-word-slugs-0.1.6.tgz",
+ "integrity": "sha512-EVPGKyhXTdnBlMCrqBvby3nf9Jz+W/rVuP2nOi68aDZa6VJ2OXvz+VDCwl8jULBLZ1Ht8wscRA+/SogeI9NYGw=="
+ },
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -17601,6 +17615,20 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-resize-detector": {
+ "version": "6.7.8",
+ "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.8.tgz",
+ "integrity": "sha512-0FaEcUBAbn+pq3PT5a9hHRebUfuS1SRLGLpIw8LydU7zX429I6XJgKerKAMPsJH0qWAl6o5bVKNqFJqr6tGPYw==",
+ "dependencies": {
+ "@types/resize-observer-browser": "^0.1.6",
+ "lodash": "^4.17.21",
+ "resize-observer-polyfill": "^1.5.1"
+ },
+ "peerDependencies": {
+ "react": "^16.0.0 || ^17.0.0",
+ "react-dom": "^16.0.0 || ^17.0.0"
+ }
+ },
"node_modules/react-router": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz",
@@ -17733,6 +17761,21 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/react-smooth": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz",
+ "integrity": "sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw==",
+ "dependencies": {
+ "fast-equals": "^2.0.0",
+ "raf": "^3.4.0",
+ "react-transition-group": "2.9.0"
+ },
+ "peerDependencies": {
+ "prop-types": "^15.6.0",
+ "react": "^15.0.0 || ^16.0.0 || ^17.0.0",
+ "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0"
+ }
+ },
"node_modules/react-transition-group": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
@@ -17805,51 +17848,6 @@
"decimal.js-light": "^2.4.1"
}
},
- "node_modules/recharts/node_modules/d3-interpolate": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
- "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
- "dependencies": {
- "d3-color": "1 - 2"
- }
- },
- "node_modules/recharts/node_modules/d3-shape": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz",
- "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==",
- "dependencies": {
- "d3-path": "1 - 2"
- }
- },
- "node_modules/recharts/node_modules/react-resize-detector": {
- "version": "6.7.8",
- "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.8.tgz",
- "integrity": "sha512-0FaEcUBAbn+pq3PT5a9hHRebUfuS1SRLGLpIw8LydU7zX429I6XJgKerKAMPsJH0qWAl6o5bVKNqFJqr6tGPYw==",
- "dependencies": {
- "@types/resize-observer-browser": "^0.1.6",
- "lodash": "^4.17.21",
- "resize-observer-polyfill": "^1.5.1"
- },
- "peerDependencies": {
- "react": "^16.0.0 || ^17.0.0",
- "react-dom": "^16.0.0 || ^17.0.0"
- }
- },
- "node_modules/recharts/node_modules/react-smooth": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz",
- "integrity": "sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw==",
- "dependencies": {
- "fast-equals": "^2.0.0",
- "raf": "^3.4.0",
- "react-transition-group": "2.9.0"
- },
- "peerDependencies": {
- "prop-types": "^15.6.0",
- "react": "^15.0.0 || ^16.0.0 || ^17.0.0",
- "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/recursive-readdir": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
@@ -19700,7 +19698,7 @@
"version": "10.8.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.0.tgz",
"integrity": "sha512-/fNd5Qh+zTt8Vt1KbYZjRHCE9sI5i7nqfD/dzBBRDeVXZXS6kToW6R7tTU6Nd4XavFs0mAVCg29Q//ML7WsZYA==",
- "devOptional": true,
+ "dev": true,
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
@@ -19743,7 +19741,7 @@
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
- "devOptional": true,
+ "dev": true,
"engines": {
"node": ">=0.4.0"
}
@@ -19752,7 +19750,7 @@
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
- "devOptional": true
+ "dev": true
},
"node_modules/tsconfig-paths": {
"version": "3.14.1",
@@ -20078,7 +20076,7 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
- "devOptional": true
+ "dev": true
},
"node_modules/v8-to-istanbul": {
"version": "8.1.1",
@@ -21000,7 +20998,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
- "devOptional": true,
+ "dev": true,
"engines": {
"node": ">=6"
}
@@ -22349,7 +22347,7 @@
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
- "devOptional": true,
+ "dev": true,
"requires": {
"@jridgewell/trace-mapping": "0.3.9"
},
@@ -22358,7 +22356,7 @@
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
- "devOptional": true,
+ "dev": true,
"requires": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
@@ -22459,14 +22457,12 @@
"@csstools/postcss-unset-value": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.1.tgz",
- "integrity": "sha512-f1G1WGDXEU/RN1TWAxBPQgQudtLnLQPyiWdtypkPC+mVYNKFKH/HYXSxH4MVNqwF8M0eDsoiU7HumJHCg/L/jg==",
- "requires": {}
+ "integrity": "sha512-f1G1WGDXEU/RN1TWAxBPQgQudtLnLQPyiWdtypkPC+mVYNKFKH/HYXSxH4MVNqwF8M0eDsoiU7HumJHCg/L/jg=="
},
"@csstools/selector-specificity": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-1.0.0.tgz",
- "integrity": "sha512-RkYG5KiGNX0fJ5YoI0f4Wfq2Yo74D25Hru4fxTOioYdQvHBxcrrtTTyT5Ozzh2ejcNrhFy7IEts2WyEY7yi5yw==",
- "requires": {}
+ "integrity": "sha512-RkYG5KiGNX0fJ5YoI0f4Wfq2Yo74D25Hru4fxTOioYdQvHBxcrrtTTyT5Ozzh2ejcNrhFy7IEts2WyEY7yi5yw=="
},
"@eslint/eslintrc": {
"version": "1.3.0",
@@ -23938,8 +23934,7 @@
"@react-types/shared": {
"version": "3.13.0",
"resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.13.0.tgz",
- "integrity": "sha512-ha+Xzn6gG/aww2nl7A6kYSJdYQypTxdYgNrJvddDB7h0QuyVQTf27iVleOWrmkHQ1TM9Q/FUbMdJ93CgdtP26g==",
- "requires": {}
+ "integrity": "sha512-ha+Xzn6gG/aww2nl7A6kYSJdYQypTxdYgNrJvddDB7h0QuyVQTf27iVleOWrmkHQ1TM9Q/FUbMdJ93CgdtP26g=="
},
"@react-types/switch": {
"version": "3.2.0",
@@ -24431,8 +24426,7 @@
"@stitches/react": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/@stitches/react/-/react-1.2.8.tgz",
- "integrity": "sha512-9g9dWI4gsSVe8bNLlb+lMkBYsnIKCZTmvqvDG+Avnn69XfmHZKiaMrx7cgTaddq7aTPPmXiTsbFcUy0xgI4+wA==",
- "requires": {}
+ "integrity": "sha512-9g9dWI4gsSVe8bNLlb+lMkBYsnIKCZTmvqvDG+Avnn69XfmHZKiaMrx7cgTaddq7aTPPmXiTsbFcUy0xgI4+wA=="
},
"@surma/rollup-plugin-off-main-thread": {
"version": "2.2.3",
@@ -24777,10 +24771,11 @@
}
},
"@tokr-labs/governance": {
- "version": "0.2.0",
- "resolved": "https://npm.pkg.github.com/download/@tokr-labs/governance/0.2.0/0d56b1583bf0bc76f75d44eb57efbf7cdd86e43684f04520693d1b4badf12ebb",
- "integrity": "sha512-wSBhLI12aHnxwu5Lmfi5qB00PeeDNro74cjcmQq9WHjW7HoXCrgtU1HnKLso1JYDWAsp3dYAs17NYdVdD4I78w==",
+ "version": "0.3.0",
+ "resolved": "https://npm.pkg.github.com/download/@tokr-labs/governance/0.3.0/89bec58861c9af343af745fa495b2cf396f2d1742de0c6de4b15b7eb3a0a19e9",
+ "integrity": "sha512-ql+gGySiFIX1TmTPisZg06exOG55hVklBhHf3tLJEQp5dU9etakBME4AyZ4/LJlc7rasOQgBx65mfA8dkb4oXg==",
"requires": {
+ "@solana/spl-token": "0.2.0",
"@solana/web3.js": "1.43.1",
"bignumber.js": "9.0.1",
"bn.js": "5.1.3",
@@ -25023,25 +25018,25 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
"integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
- "devOptional": true
+ "dev": true
},
"@tsconfig/node12": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
"integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
- "devOptional": true
+ "dev": true
},
"@tsconfig/node14": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
"integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
- "devOptional": true
+ "dev": true
},
"@tsconfig/node16": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
- "devOptional": true
+ "dev": true
},
"@types/amplitude-js": {
"version": "8.16.0",
@@ -25310,7 +25305,7 @@
"version": "16.11.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.36.tgz",
"integrity": "sha512-FR5QJe+TaoZ2GsMHkjuwoNabr+UrJNRr2HNOo+r/7vhcuntM6Ee/pRPOnRhhL2XE9OOvX9VLEq+BcXl3VjNoWA==",
- "devOptional": true
+ "dev": true
},
"@types/parse-json": {
"version": "4.0.0",
@@ -25670,8 +25665,7 @@
"@use-it/event-listener": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/@use-it/event-listener/-/event-listener-0.1.7.tgz",
- "integrity": "sha512-hgfExDzUU9uTRTPDCpw2s9jWTxcxmpJya3fK5ADpf5VDpSy8WYwY/kh28XE0tUcbsljeP8wfan48QvAQTSSa3Q==",
- "requires": {}
+ "integrity": "sha512-hgfExDzUU9uTRTPDCpw2s9jWTxcxmpJya3fK5ADpf5VDpSy8WYwY/kh28XE0tUcbsljeP8wfan48QvAQTSSa3Q=="
},
"@webassemblyjs/ast": {
"version": "1.11.1",
@@ -25857,14 +25851,12 @@
"acorn-import-assertions": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
- "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
- "requires": {}
+ "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw=="
},
"acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "requires": {}
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="
},
"acorn-node": {
"version": "1.8.2",
@@ -26261,8 +26253,7 @@
"ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
- "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "requires": {}
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
},
"json-schema-traverse": {
"version": "0.4.1",
@@ -26335,8 +26326,7 @@
"babel-plugin-named-asset-import": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz",
- "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==",
- "requires": {}
+ "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q=="
},
"babel-plugin-polyfill-corejs2": {
"version": "0.3.1",
@@ -26533,9 +26523,9 @@
"integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w=="
},
"bn.js": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
- "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
},
"body-parser": {
"version": "1.20.0",
@@ -27255,7 +27245,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
- "devOptional": true
+ "dev": true
},
"cross-fetch": {
"version": "3.1.5",
@@ -27333,8 +27323,7 @@
"css-declaration-sorter": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.2.2.tgz",
- "integrity": "sha512-Ufadglr88ZLsrvS11gjeu/40Lw74D9Am/Jpr3LlYm5Q4ZP5KdlUhG+6u2EjyXeZcxmZ2h1ebCKngDjolpeLHpg==",
- "requires": {}
+ "integrity": "sha512-Ufadglr88ZLsrvS11gjeu/40Lw74D9Am/Jpr3LlYm5Q4ZP5KdlUhG+6u2EjyXeZcxmZ2h1ebCKngDjolpeLHpg=="
},
"css-has-pseudo": {
"version": "3.0.4",
@@ -27401,8 +27390,7 @@
"css-prefers-color-scheme": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz",
- "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==",
- "requires": {}
+ "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA=="
},
"css-select": {
"version": "2.1.0",
@@ -27511,8 +27499,7 @@
"cssnano-utils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
- "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
- "requires": {}
+ "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA=="
},
"csso": {
"version": "4.2.0",
@@ -27568,28 +27555,36 @@
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz",
"integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA=="
},
+ "d3-array": {
+ "version": "2.12.1",
+ "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
+ "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
+ "requires": {
+ "internmap": "^1.0.0"
+ }
+ },
"d3-color": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz",
- "integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
+ "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
},
"d3-format": {
- "version": "1.4.5",
- "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz",
- "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz",
+ "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA=="
},
"d3-interpolate": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz",
- "integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
+ "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
"requires": {
- "d3-color": "1"
+ "d3-color": "1 - 2"
}
},
"d3-path": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
- "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz",
+ "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA=="
},
"d3-scale": {
"version": "3.3.0",
@@ -27601,37 +27596,30 @@
"d3-interpolate": "1.2.0 - 2",
"d3-time": "^2.1.1",
"d3-time-format": "2 - 3"
- },
- "dependencies": {
- "d3-array": {
- "version": "2.12.1",
- "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
- "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
- "requires": {
- "internmap": "^1.0.0"
- }
- },
- "d3-time": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
- "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
- "requires": {
- "d3-array": "2"
- }
- }
+ }
+ },
+ "d3-shape": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz",
+ "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==",
+ "requires": {
+ "d3-path": "1 - 2"
}
},
"d3-time": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz",
- "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA=="
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
+ "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
+ "requires": {
+ "d3-array": "2"
+ }
},
"d3-time-format": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.3.0.tgz",
- "integrity": "sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz",
+ "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==",
"requires": {
- "d3-time": "1"
+ "d3-time": "1 - 2"
}
},
"damerau-levenshtein": {
@@ -27852,7 +27840,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
- "devOptional": true
+ "dev": true
},
"diff-sequences": {
"version": "27.5.1",
@@ -28117,8 +28105,7 @@
"ws": {
"version": "8.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
- "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
- "requires": {}
+ "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA=="
}
}
},
@@ -28671,8 +28658,7 @@
"eslint-plugin-react-hooks": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz",
- "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==",
- "requires": {}
+ "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw=="
},
"eslint-plugin-testing-library": {
"version": "5.5.1",
@@ -29203,8 +29189,7 @@
"ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
- "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "requires": {}
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
},
"ansi-styles": {
"version": "4.3.0",
@@ -29824,8 +29809,7 @@
"icss-utils": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
- "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
- "requires": {}
+ "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA=="
},
"idb": {
"version": "6.1.5",
@@ -30179,8 +30163,7 @@
"isomorphic-ws": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz",
- "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==",
- "requires": {}
+ "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w=="
},
"istanbul-lib-coverage": {
"version": "3.2.0",
@@ -30991,8 +30974,7 @@
"jest-pnp-resolver": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
- "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
- "requires": {}
+ "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w=="
},
"jest-regex-util": {
"version": "27.5.1",
@@ -32170,7 +32152,7 @@
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
- "devOptional": true
+ "dev": true
},
"makeerror": {
"version": "1.0.12",
@@ -32938,8 +32920,7 @@
"postcss-browser-comments": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz",
- "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==",
- "requires": {}
+ "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg=="
},
"postcss-calc": {
"version": "8.2.4",
@@ -33005,8 +32986,7 @@
"postcss-custom-media": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.0.tgz",
- "integrity": "sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g==",
- "requires": {}
+ "integrity": "sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g=="
},
"postcss-custom-properties": {
"version": "12.1.7",
@@ -33035,26 +33015,22 @@
"postcss-discard-comments": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.1.tgz",
- "integrity": "sha512-5JscyFmvkUxz/5/+TB3QTTT9Gi9jHkcn8dcmmuN68JQcv3aQg4y88yEHHhwFB52l/NkaJ43O0dbksGMAo49nfQ==",
- "requires": {}
+ "integrity": "sha512-5JscyFmvkUxz/5/+TB3QTTT9Gi9jHkcn8dcmmuN68JQcv3aQg4y88yEHHhwFB52l/NkaJ43O0dbksGMAo49nfQ=="
},
"postcss-discard-duplicates": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz",
- "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==",
- "requires": {}
+ "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw=="
},
"postcss-discard-empty": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz",
- "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==",
- "requires": {}
+ "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A=="
},
"postcss-discard-overridden": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz",
- "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==",
- "requires": {}
+ "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw=="
},
"postcss-double-position-gradients": {
"version": "3.1.1",
@@ -33076,8 +33052,7 @@
"postcss-flexbugs-fixes": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz",
- "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==",
- "requires": {}
+ "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ=="
},
"postcss-focus-visible": {
"version": "6.0.4",
@@ -33098,14 +33073,12 @@
"postcss-font-variant": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz",
- "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==",
- "requires": {}
+ "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA=="
},
"postcss-gap-properties": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.3.tgz",
- "integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ==",
- "requires": {}
+ "integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ=="
},
"postcss-image-set-function": {
"version": "4.0.6",
@@ -33118,8 +33091,7 @@
"postcss-initial": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz",
- "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==",
- "requires": {}
+ "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ=="
},
"postcss-js": {
"version": "4.0.0",
@@ -33160,14 +33132,12 @@
"postcss-logical": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz",
- "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==",
- "requires": {}
+ "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g=="
},
"postcss-media-minmax": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz",
- "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==",
- "requires": {}
+ "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ=="
},
"postcss-merge-longhand": {
"version": "5.1.5",
@@ -33228,8 +33198,7 @@
"postcss-modules-extract-imports": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
- "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
- "requires": {}
+ "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw=="
},
"postcss-modules-local-by-default": {
"version": "4.0.0",
@@ -33287,8 +33256,7 @@
"postcss-normalize-charset": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
- "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==",
- "requires": {}
+ "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg=="
},
"postcss-normalize-display-values": {
"version": "5.1.0",
@@ -33373,14 +33341,12 @@
"postcss-overflow-shorthand": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.3.tgz",
- "integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg==",
- "requires": {}
+ "integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg=="
},
"postcss-page-break": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz",
- "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==",
- "requires": {}
+ "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ=="
},
"postcss-place": {
"version": "7.0.4",
@@ -33471,8 +33437,7 @@
"postcss-replace-overflow-wrap": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz",
- "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==",
- "requires": {}
+ "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw=="
},
"postcss-selector-not": {
"version": "5.0.0",
@@ -33785,6 +33750,11 @@
"performance-now": "^2.1.0"
}
},
+ "random-word-slugs": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/random-word-slugs/-/random-word-slugs-0.1.6.tgz",
+ "integrity": "sha512-EVPGKyhXTdnBlMCrqBvby3nf9Jz+W/rVuP2nOi68aDZa6VJ2OXvz+VDCwl8jULBLZ1Ht8wscRA+/SogeI9NYGw=="
+ },
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -33959,8 +33929,7 @@
"react-icons": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.4.0.tgz",
- "integrity": "sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg==",
- "requires": {}
+ "integrity": "sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg=="
},
"react-interactive": {
"version": "0.8.3",
@@ -33987,6 +33956,16 @@
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A=="
},
+ "react-resize-detector": {
+ "version": "6.7.8",
+ "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.8.tgz",
+ "integrity": "sha512-0FaEcUBAbn+pq3PT5a9hHRebUfuS1SRLGLpIw8LydU7zX429I6XJgKerKAMPsJH0qWAl6o5bVKNqFJqr6tGPYw==",
+ "requires": {
+ "@types/resize-observer-browser": "^0.1.6",
+ "lodash": "^4.17.21",
+ "resize-observer-polyfill": "^1.5.1"
+ }
+ },
"react-router": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz",
@@ -34090,6 +34069,16 @@
}
}
},
+ "react-smooth": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz",
+ "integrity": "sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw==",
+ "requires": {
+ "fast-equals": "^2.0.0",
+ "raf": "^3.4.0",
+ "react-transition-group": "2.9.0"
+ }
+ },
"react-transition-group": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
@@ -34135,44 +34124,6 @@
"react-smooth": "^2.0.0",
"recharts-scale": "^0.4.4",
"reduce-css-calc": "^2.1.8"
- },
- "dependencies": {
- "d3-interpolate": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
- "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
- "requires": {
- "d3-color": "1 - 2"
- }
- },
- "d3-shape": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz",
- "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==",
- "requires": {
- "d3-path": "1 - 2"
- }
- },
- "react-resize-detector": {
- "version": "6.7.8",
- "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.8.tgz",
- "integrity": "sha512-0FaEcUBAbn+pq3PT5a9hHRebUfuS1SRLGLpIw8LydU7zX429I6XJgKerKAMPsJH0qWAl6o5bVKNqFJqr6tGPYw==",
- "requires": {
- "@types/resize-observer-browser": "^0.1.6",
- "lodash": "^4.17.21",
- "resize-observer-polyfill": "^1.5.1"
- }
- },
- "react-smooth": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz",
- "integrity": "sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw==",
- "requires": {
- "fast-equals": "^2.0.0",
- "raf": "^3.4.0",
- "react-transition-group": "2.9.0"
- }
- }
}
},
"recharts-scale": {
@@ -34584,8 +34535,7 @@
"ws": {
"version": "8.7.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz",
- "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==",
- "requires": {}
+ "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg=="
}
}
},
@@ -34680,8 +34630,7 @@
"ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
- "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "requires": {}
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
},
"json-schema-traverse": {
"version": "0.4.1",
@@ -35242,8 +35191,7 @@
"style-loader": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz",
- "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==",
- "requires": {}
+ "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ=="
},
"stylehacks": {
"version": "5.1.0",
@@ -35574,7 +35522,7 @@
"version": "10.8.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.0.tgz",
"integrity": "sha512-/fNd5Qh+zTt8Vt1KbYZjRHCE9sI5i7nqfD/dzBBRDeVXZXS6kToW6R7tTU6Nd4XavFs0mAVCg29Q//ML7WsZYA==",
- "devOptional": true,
+ "dev": true,
"requires": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
@@ -35595,13 +35543,13 @@
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
- "devOptional": true
+ "dev": true
},
"arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
- "devOptional": true
+ "dev": true
}
}
},
@@ -35855,7 +35803,7 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
- "devOptional": true
+ "dev": true
},
"v8-to-istanbul": {
"version": "8.1.1",
@@ -36098,8 +36046,7 @@
"ws": {
"version": "8.7.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz",
- "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==",
- "requires": {}
+ "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg=="
}
}
},
@@ -36526,8 +36473,7 @@
"ws": {
"version": "7.5.8",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz",
- "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==",
- "requires": {}
+ "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw=="
},
"xml-name-validator": {
"version": "3.0.0",
@@ -36587,7 +36533,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
- "devOptional": true
+ "dev": true
},
"yocto-queue": {
"version": "0.1.0",
diff --git a/package.json b/package.json
index 6f758ac..c7e3c9f 100644
--- a/package.json
+++ b/package.json
@@ -2,6 +2,9 @@
"name": "tokr-fi",
"version": "0.1.0",
"private": true,
+ "engines": {
+ "node": ">=16"
+ },
"scripts": {
"start": "craco start",
"test": "craco test",
@@ -46,6 +49,7 @@
}
},
"dependencies": {
+ "bn.js": "5.2.0",
"@nextui-org/react": "1.0.0-beta.9",
"@project-serum/common": "0.0.1-beta.3",
"@solana/buffer-layout-utils": "0.2.0",
@@ -58,7 +62,7 @@
"@solana/wallet-adapter-wallets": "0.15.5",
"@solana/web3.js": "1.43.1",
"@tokr-labs/cap-table": "0.3.0",
- "@tokr-labs/governance": "0.2.0",
+ "@tokr-labs/governance": "0.3.0",
"@tokr-labs/identity-verification": "0.7.0",
"amplitude-js": "8.18.1",
"boxicons": "2.1.2",
@@ -73,7 +77,8 @@
"typescript": "4.7.2",
"underscore": "1.13.2",
"use-dark-mode": "2.3.1",
- "web-vitals": "2.1.4"
+ "web-vitals": "2.1.4",
+ "random-word-slugs": "0.1.6"
},
"devDependencies": {
"@craco/craco": "6.4.3",
diff --git a/src/assets/create-dao-config.localnet.json b/src/assets/create-dao-config.localnet.json
new file mode 100644
index 0000000..26e441b
--- /dev/null
+++ b/src/assets/create-dao-config.localnet.json
@@ -0,0 +1,51 @@
+{
+ "governanceProgramId": "5Hyx5g6n82uZpVYRLZqssLSj5V6mZc2QYQFtPcj83Jp2",
+ "name": "",
+ "description": "Miami Fund is a private real estate investment fund focused on producing market-beating returns through a disciplined, value-add investing approach in one of the fastest growing markets in the world, Miami, FL. We pride ourselves on sourcing proprietary deal-flow below-market, and generating opportunities in under-managed assets.",
+ "active": false,
+ "strategy": 0,
+ "token": {
+ "ticker": "",
+ "image": "https://dummyimage.com/100x100/000/fff"
+ },
+ "stakeholders": {
+ "sponsor": {
+ "name": "John Smith",
+ "company": "Smith & Co. Investments",
+ "image": "https://dummyimage.com/400x400/000/fff"
+ },
+ "delegate": {
+ "name": "Tokr Labs",
+ "company": "Tokr Labs",
+ "image": "https://dummyimage.com/400x400/000/fff"
+ }
+ },
+ "details": {
+ "minRaise": 7500000,
+ "maxRaise": 10000000,
+ "minInvestment": 100000,
+ "raiseClose": 1672531200,
+ "vintageYear": "2022",
+ "fundTerm": 5,
+ "dataRoom": "",
+ "targetReturns": {
+ "irr": 2400,
+ "coc": 1000,
+ "tvpi": 430,
+ "dpi": 210
+ },
+ "fees": {
+ "closing": 1000,
+ "annual": 1000
+ }
+ },
+ "governance": {
+ "voteThresholdPercentage": 25,
+ "minCommunityTokensToCreateProposal": 10000000,
+ "minInstructionHoldUpTime": 0,
+ "maxVotingTime": 259250,
+ "voteTipping": 0,
+ "proposalCoolOffTime": 0,
+ "minCouncilTokensToCreateProposal": 1
+ }
+}
diff --git a/src/components/CreateFund.tsx b/src/components/CreateFund.tsx
new file mode 100644
index 0000000..35d7dc7
--- /dev/null
+++ b/src/components/CreateFund.tsx
@@ -0,0 +1,384 @@
+import React, { useEffect, useMemo, useState } from "react";
+import { Modal, Button, Text, Input, Row, Checkbox, Dropdown, Grid, Spacer, Textarea, Table, Container, Progress, StyledContainer, Collapse, Col, theme } from "@nextui-org/react";
+import TargetReturns from "./create-fund-views/TargetReturns";
+import KeyValueTable from "./create-fund-views/KeyValueTable";
+import Stakeholders from "./create-fund-views/Stakeholders";
+import FundName from "./create-fund-views/FundName";
+import FundConfig from "./create-fund-views/FundConfig";
+import FundInvestment from "./create-fund-views/FundInvestment";
+import { useConnection, useWallet } from "@solana/wallet-adapter-react";
+import { CreateDaoAction } from "src/services/actions/create-dao-action";
+import { IoIosArrowBack } from "react-icons/io";
+
+
+enum FundCreationStep {
+ // fund creator sets the high-level information about the fund
+ NAME,
+
+ // fund creator sets the various stakeholders for the fund
+ STAKEHOLDERS,
+
+ // fund creator sets property data (i.e. asset type / class)
+ FUND_CONFIG,
+
+ // fund creator sets the investment terms of the fund
+ FUND_INVESTMENT,
+
+ // fund creator sets the expected/target capital returns of the fund
+ TARGET_RETURNS,
+
+ // final review before solana transaction submission
+ SUBMIT
+}
+
+// Determines the ordering of fund creation stages
+export const FundCreationOrder = [
+ FundCreationStep.NAME,
+ FundCreationStep.STAKEHOLDERS,
+ FundCreationStep.FUND_CONFIG,
+ FundCreationStep.FUND_INVESTMENT,
+ FundCreationStep.TARGET_RETURNS,
+ FundCreationStep.SUBMIT
+]
+
+export const CreateFund = (props) => {
+ // determines if the modal is open or not
+ const [visible, setVisible] = useState(false);
+
+ // determines which "page" of the modal should be conditionally rendered
+ // i.e. depending on the step, different inputs are rendered for the user
+ const [step, setStep] = useState(FundCreationStep.NAME);
+
+ // indicate if the user has scrolled to the bottom
+ // will be used for enabling the `Create` button
+ const [scrolledToBottom, setScrolledToBottom] = useState(false);
+
+ // User-input is captured in these state variables below
+ // each of the state variables are provided to child views as props
+
+ // Form state -- Name & Info
+ const [fundName, setFundName] = useState();
+ const [fundDescription, setFundDescription] = useState();
+ const [tokenSymbol, setTokenSymbol] = useState();
+ const [minRaise, setMinRaise] = useState();
+ const [maxRaise, setMaxRaise] = useState();
+ const [minInvestment, setMinInvestment] = useState();
+ const [closingFee, setClosingFee] = useState();
+ const [annualFee, setAnnualFee] = useState();
+
+ // Form state -- Stakeholders
+ const [sponsorName, setSponsorName] = useState();
+ const [sponsorCompany, setSponsorCompany] = useState();
+ const [delegateName, setDelegateName] = useState();
+ const [delegateCompany, setDelegateCompany] = useState();
+ const [delegateAccount, setDelegateAccount] = useState();
+
+ // Form state -- Fund Configuration
+ const [assetType, setAssetType] = useState(new Set([]));
+ const [assetClass, setAssetClass] = useState(new Set([]));
+ const [assetVintage, setAssetVintage] = useState();
+ const [assetSize, setAssetSize] = useState();
+ const [targetMarket, setTargetMarket] = useState();
+ const formattedAssetClass = useMemo(
+ () => {
+ return Array.from(assetClass).sort().join(", ").replaceAll("_", " ")
+ },
+ [assetClass]
+ );
+ const [strategy, setStrategy] = useState();
+ const [fundTerm, setFundTerm] = useState();
+
+ // Form state -- Target Returns
+ const [irr, setIRR] = useState();
+ const [coc, setCOC] = useState();
+ const [tvpi, setTVPI] = useState();
+ const [dpi, setDPI] = useState();
+
+ // capture and structure all user input, which will be
+ // presented as a final review before
+ // solana transaction is broadcasted
+ const infoData = [
+ {name: 'Fund Name', value: fundName},
+ {name: 'Token Symbol', value: tokenSymbol},
+ {name: 'Description', value: fundDescription},
+ ]
+ const stakeholderData = [
+ {name: 'Sponsor', value: sponsorName},
+ {name: 'Sponsor Company', value: sponsorCompany},
+ {name: 'Delegate', value: delegateName},
+ {name: 'Delegate Company', value: delegateCompany},
+ {name: 'Delegate Account', value: delegateAccount}
+ ]
+ const fundConfigData = [
+ {name: 'Asset Type', value: assetType},
+ {name: 'Asset Class', value: assetClass},
+ {name: 'Asset Vintage', value: assetVintage},
+ {name: 'Asset Size', value: assetSize},
+ {name: 'Target Market', value: targetMarket},
+ {name: 'Investment Strategy', value: strategy},
+ {name: 'Fund Term', value: fundTerm}
+ ]
+ const investmentData = [
+ {name: 'Minimum Raise', value: minRaise},
+ {name: 'Maximum Raise', value: maxRaise},
+ {name: 'Minimum Investment', value: minInvestment},
+ {name: 'Closing Fee', value: closingFee},
+ {name: 'Annual Fee', value: annualFee}
+ ]
+ const returnData = [
+ {name: 'Internal Rate of Return', value: irr},
+ {name: 'Cash on Cash', value: coc},
+ {name: 'Total Value to Paid-in', value: tvpi},
+ {name: 'Distributions to Paid-in', value: dpi},
+ ]
+
+ // styling objects
+ const navigationStyle: object = {marginLeft: 'auto', marginRight: 'auto', borderRadius: theme.radii.pill.computedValue}
+
+ const closeHandler = () => {
+ setVisible(false);
+ }
+
+ // handle the user's scroll event, setting to `true` when scrolled to the bottom
+ const handleScroll = (e) => {
+ const bottom = e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight;
+ setScrolledToBottom(bottom);
+ }
+
+ // wallet & web3 vars
+ const {connection} = useConnection();
+ const wallet = useWallet();
+ const createDaoAction = useMemo(() => {
+ return new CreateDaoAction(connection, wallet);
+ }, [connection, wallet]);
+
+ // handle when the next button is clicked
+ const handleNext = () => {
+ const currentStepIndex = FundCreationOrder.indexOf(step);
+ // newStepIndex should not index outside of FundCreationOrder (array)
+ const newStepIndex = currentStepIndex + 1;
+
+ // if the current step is the very last, we're ready to submit the transaction
+ // Construct & broadcast solana transaction here
+ if (currentStepIndex === FundCreationOrder.length - 1) {
+ // consolidate all state vars into an object and provide to CreateDaoAction.execute()
+ // @TODO: on board more user-input into the DAO creation transaction
+ const params = {
+ name: fundName,
+ details: {maxRaise},
+ governance: {
+ voteThresholdPercentage: 25,
+ minCommunityTokensToCreateProposal: 10000000,
+ minCouncilTokensToCreateProposal: 1,
+ minInstructionHoldUpTime: 0,
+ maxVotingTime: 259250,
+ voteTipping: 0,
+ proposalCoolOffTime: 0,
+ }
+ }
+
+ // broadcasts multiple transactions for DAO creation
+ createDaoAction.execute(params)
+ .then(() => console.log("dao created"))
+ .catch(err => alert(err.message));
+
+ // close the modal & reset the step
+ // @TODO: clear out the data in the form
+ setVisible(false);
+ setStep(FundCreationStep.NAME);
+ } else {
+ // advance to the next stage of fund creation
+ setStep(FundCreationOrder[newStepIndex]);
+ }
+ }
+
+ // handle when the Back button is clicked
+ const handleBack = () => {
+ const currentStepIndex = FundCreationOrder.indexOf(step);
+ // cannot go back past index 0 (FundCreationStep.NAME)
+ const newStepIndex = 0 <= currentStepIndex - 1 ? currentStepIndex - 1 : 0;
+ setStep(FundCreationOrder[newStepIndex]);
+ }
+
+ return (
+ <>
+
+
+
+
+ {
+ step !== FundCreationOrder[0] &&
+
+
+
+ }
+
+
+
+ Create Fund
+
+
+ {/* Conditionally render the subheader based on the current step */}
+
+ {
+ step === FundCreationStep.NAME ?
+ "Fund Name & Info" :
+ step === FundCreationStep.STAKEHOLDERS ?
+ "Stakeholder Information" :
+ step === FundCreationStep.FUND_CONFIG ?
+ "Fund Configuration" :
+ step === FundCreationStep.FUND_INVESTMENT ?
+ "Fund Investment" :
+ step === FundCreationStep.TARGET_RETURNS ?
+ "Target Returns" :
+ step === FundCreationStep.SUBMIT ?
+ "Review" : ""
+ }
+
+
+
+
+
+
+
+
+
+
+ {/* Body of the modal if conditionally rendered dependent on `FundCreateStep` */}
+ {
+ step === FundCreationStep.NAME &&
+ <>
+
+ >
+ }
+ {
+ step === FundCreationStep.STAKEHOLDERS &&
+ <>
+
+ >
+ }
+ {
+ step === FundCreationStep.FUND_CONFIG &&
+ <>
+
+ >
+ }
+ {
+ step === FundCreationStep.FUND_INVESTMENT &&
+ <>
+
+ >
+ }
+ {
+ step === FundCreationStep.TARGET_RETURNS &&
+
+ }
+ {
+ step === FundCreationStep.SUBMIT &&
+
+ Fund Name & Info} expanded>
+
+
+ Stakeholders} expanded>
+
+
+ Configuration} expanded>
+
+
+ Investment} expanded>
+
+
+ Returns} expanded>
+
+
+
+ }
+
+
+
+
+
+
+
+ >
+ )
+
+}
+
+
diff --git a/src/components/create-fund-views/FundConfig.tsx b/src/components/create-fund-views/FundConfig.tsx
new file mode 100644
index 0000000..693cf0d
--- /dev/null
+++ b/src/components/create-fund-views/FundConfig.tsx
@@ -0,0 +1,131 @@
+import { Grid, Input, Dropdown, Button, Text, theme, Spacer } from '@nextui-org/react';
+import React from 'react'
+
+const FundConfig = (props) => {
+ const validAssetClasses = ["A", "B", "C", "D"];
+ const [showCustomFundTerm, setShowCustomFundTerm] = React.useState(false);
+
+ const onClickFundTerm = (value: number | undefined) => {
+ props.setFundTerm(value);
+ setShowCustomFundTerm(false);
+ }
+
+ // styling for dropdown buttons
+ const dropDownButtonStyle: object = {borderRadius: 19, textTransform: "capitalize"};
+ return (
+ <>
+ {props.fundName}
+ Details about the target property
+
+
+
+
+
+ {props.assetType.size === 0 ? "Asset Type" : props.assetType}
+
+
+ Multifamily
+ Commercial
+ Industrial
+
+
+
+
+
+
+
+ {props.assetClass.size === 0 ? "Asset Class" : `Class ${props.formattedAssetClass}`}
+
+
+ {validAssetClasses.map((classLetter) => {
+ return (
+ {`Class ${classLetter}`}
+ )
+ })
+ }
+
+
+
+
+ props.setAssetVintage(event.target.value)}/>
+
+
+ props.setAssetSize(event.target.value)}/>
+
+
+ props.setTargetMarket(event.target.value)}/>
+
+
+ props.setStrategy(event.target.value)}/>
+
+
+
+ Fund Term (Years):
+
+
+
+
+
+
+
+
+ {/* Initially show the "Custom" button, but on-click change it to an input */}
+ {!showCustomFundTerm ? (
+
+ ) : (
+ {onClickFundTerm(undefined)}}
+ value={props.fundTerm} onChange={event => props.setFundTerm(event.target.value)}
+ />
+ )}
+
+
+
+
+ {/* Comically impractical -- wen slider??
+
+ Fund Term
+
+ {
+ fundTermYears.map((year) => {
+ return (
+ {year}
+ )
+ })
+ }
+
+ */}
+
+ >
+ )
+};
+
+export default FundConfig;
\ No newline at end of file
diff --git a/src/components/create-fund-views/FundInvestment.tsx b/src/components/create-fund-views/FundInvestment.tsx
new file mode 100644
index 0000000..6c270e6
--- /dev/null
+++ b/src/components/create-fund-views/FundInvestment.tsx
@@ -0,0 +1,36 @@
+import { Grid, Input, Spacer, Text } from '@nextui-org/react';
+import React from 'react'
+
+const FundInvestment = (props) => {
+ return (
+ <>
+ {props.fundName}
+ Details regarding the terms of investment such as minimums and maximums
+
+
+
+ props.setMinRaise(event.target.value)}/>
+
+
+ props.setMaxRaise(event.target.value)}/>
+
+
+ props.setMinInvestment(event.target.value)}/>
+
+
+
+ Associated Fees of the Fund
+
+
+
+ props.setAnnualFee(event.target.value)}/>
+
+
+ props.setClosingFee(event.target.value)}/>
+
+
+ >
+ )
+};
+
+export default FundInvestment;
\ No newline at end of file
diff --git a/src/components/create-fund-views/FundName.tsx b/src/components/create-fund-views/FundName.tsx
new file mode 100644
index 0000000..c8b587c
--- /dev/null
+++ b/src/components/create-fund-views/FundName.tsx
@@ -0,0 +1,28 @@
+import { Grid, Input, Spacer, Textarea, Text } from '@nextui-org/react';
+import React from 'react'
+
+const FundName = (props) => {
+ return (
+ <>
+ Initial information about the fund
+
+
+
+
+ props.setFundName(event.target.value)}/>
+
+
+ props.setTokenSymbol(event.target.value)}/>
+
+
+
+
+
+
+
+ >
+ )
+};
+
+export default FundName;
\ No newline at end of file
diff --git a/src/components/create-fund-views/KeyValueTable.tsx b/src/components/create-fund-views/KeyValueTable.tsx
new file mode 100644
index 0000000..69eabbb
--- /dev/null
+++ b/src/components/create-fund-views/KeyValueTable.tsx
@@ -0,0 +1,32 @@
+import {Table} from "@nextui-org/react";
+import React from "react";
+
+const KeyValueTable = (props) => {
+ return (
+ <>
+
+
+ {props.keyString}
+ {props.valueString}
+
+
+ {
+ props.data.map((row, i) => {
+ return (
+
+ {row.name}
+ {row.value}
+
+ )
+ })
+ }
+
+
+ >
+ )
+};
+
+export default KeyValueTable;
\ No newline at end of file
diff --git a/src/components/create-fund-views/Stakeholders.tsx b/src/components/create-fund-views/Stakeholders.tsx
new file mode 100644
index 0000000..f7094e8
--- /dev/null
+++ b/src/components/create-fund-views/Stakeholders.tsx
@@ -0,0 +1,35 @@
+import { Grid, Input, Spacer, Text } from '@nextui-org/react';
+import React from 'react'
+
+const Stakeholders = (props) => {
+ return (
+ <>
+ {props.fundName}
+ Details & contact information regarding stakeholders and overseers of the Fund
+
+
+
+
+ props.setSponsorName(event.target.value)}/>
+
+
+ props.setSponsorCompany(event.target.value)}/>
+
+
+
+
+ props.setDelegateAccount(event.target.value)}/>
+
+
+ props.setDelegateName(event.target.value)}/>
+
+
+ props.setDelegateCompany(event.target.value)}/>
+
+
+
+ >
+ )
+};
+
+export default Stakeholders;
\ No newline at end of file
diff --git a/src/components/create-fund-views/TargetReturns.tsx b/src/components/create-fund-views/TargetReturns.tsx
new file mode 100644
index 0000000..bea8165
--- /dev/null
+++ b/src/components/create-fund-views/TargetReturns.tsx
@@ -0,0 +1,42 @@
+import {Input, Grid, Text, Spacer} from "@nextui-org/react";
+import React, {useMemo, useState} from "react";
+
+const TargetReturns = (props) => {
+ return (
+ <>
+ {props.fundName}
+ Approximate or expected returns of the property & fund
+
+ {/* @TODO: input validation -- limit to 2 decimals and must be in the range of [0, 100] */}
+
+
+ props.setIRR(event.target.value)}
+ />
+
+
+ props.setCOC(event.target.value)}
+ />
+
+
+ props.setTVPI(event.target.value)}
+ />
+
+
+
+ props.setDPI(event.target.value)}
+ />
+
+
+ >
+ )
+};
+
+export default TargetReturns;
\ No newline at end of file
diff --git a/src/components/sub-navbar.tsx b/src/components/sub-navbar.tsx
index 05d982e..689ac8a 100644
--- a/src/components/sub-navbar.tsx
+++ b/src/components/sub-navbar.tsx
@@ -1,14 +1,18 @@
-import React, {useState} from "react";
+import React, {useMemo, useState} from "react";
import {Button, Grid, theme, Tooltip} from "@nextui-org/react";
import {Link, useLocation, useNavigate} from "react-router-dom";
+import {CreateDaoAction} from "../services/actions/create-dao-action";
+import { CreateFund } from "./CreateFund";
import {IoIosArrowBack} from "react-icons/io";
+import {useConnection, useWallet} from "@solana/wallet-adapter-react";
export const SubNavbar = () => {
const markets = ["EQUITY MARKET", "DEBT MARKET"]
const [selected, setSelected] = useState(markets[0]);
-
+ const connection = useConnection().connection;
+ const wallet = useWallet();
const location = useLocation();
const navigate = useNavigate();
@@ -18,6 +22,28 @@ export const SubNavbar = () => {
navigate(market.split(" ")[0].toLowerCase())
}
+ // styling object for the buttons
+ const buttonStyle = {
+ letterSpacing: "1px",
+ padding: "0 30px",
+ borderRadius: theme.radii.pill.computedValue,
+ fontWeight: theme.fontWeights.bold.computedValue,
+ }
+
+
+ const createDaoAction = useMemo(() => {
+ return new CreateDaoAction(connection, wallet);
+ }, [connection, wallet])
+
+ const createDao = () => {
+
+ const info = require("../assets/create-dao-config.localnet.json")
+ createDaoAction.execute(info)
+ .then(() => console.log("dao created"))
+ .catch(err => console.error(err.message));
+
+ }
+
if (location.pathname.split("/").length > 3) {
return (
@@ -51,11 +77,7 @@ export const SubNavbar = () => {
)
+
+
})}
+
+
+
>
)
diff --git a/src/models/action-protocol.ts b/src/models/action-protocol.ts
index 2e38b8a..419c972 100644
--- a/src/models/action-protocol.ts
+++ b/src/models/action-protocol.ts
@@ -3,6 +3,6 @@ import {SimulatedTransactionResponse, TransactionSignature} from "@solana/web3.j
export interface ActionProtocol {
execute(...args): Promise
- simulate(...args): Promise
+ simulate(...args): Promise
}
diff --git a/src/models/constants.ts b/src/models/constants.ts
index 44bce40..643ed38 100644
--- a/src/models/constants.ts
+++ b/src/models/constants.ts
@@ -1,10 +1,12 @@
import {PublicKey} from "@solana/web3.js";
// @TODO: Move this to the client side env
+export const USDC_LOCALNET = new PublicKey("8GM1dEZR6sL9Kut9GpSuPC5FTVCANeTNJrq31bepuDXU")
export const USDC_DEVNET = new PublicKey("DjrL2ATiHzTg5Rg2EFD24gbV3vLBkeX9Hw29u1KyF15r")
export const USDC_MAINNET = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v")
export const GOVERNANCE_PROGRAM_ID = new PublicKey("CCzEwDHqNqq4KL4srnRKQeQ7P9Aa1uoAQmkz1kWFc2rd");
+export const GOVERNANCE_PROGRAM_LOCALNET_ID = new PublicKey("5Hyx5g6n82uZpVYRLZqssLSj5V6mZc2QYQFtPcj83Jp2");
export const IDENTITY_VERIFICATION_PROGRAM_ID = new PublicKey("5WJNeGKQQJMaTCPgtXhmsiEK4bA6dLT94smLFmTU8Gh9");
export const IDENTITY_VERIFICATION_INITIAL_AUTHORITY = new PublicKey("ANDKyhwCrWMagosngR44NuhGwHEtGD8r2ML3u4VkD14L");
export const TOKR_SERVICE_ENDPOINT_DEVNET = "https://tokr-services.herokuapp.com"
diff --git a/src/models/dao/dao-stakeholder.ts b/src/models/dao/dao-stakeholder.ts
index 4ab75ec..6ce96f2 100644
--- a/src/models/dao/dao-stakeholder.ts
+++ b/src/models/dao/dao-stakeholder.ts
@@ -18,8 +18,6 @@ export class DaoStakeholder {
stakeholder.company = info?.company ?? "";
stakeholder.image = info?.image ?? "";
- console.log("image = ", stakeholder.image);
-
return stakeholder;
}
diff --git a/src/services/actions/create-dao-action.ts b/src/services/actions/create-dao-action.ts
new file mode 100644
index 0000000..0186bec
--- /dev/null
+++ b/src/services/actions/create-dao-action.ts
@@ -0,0 +1,721 @@
+import {
+ Blockhash,
+ BlockheightBasedTransactionConfirmationStrategy, Commitment,
+ Connection,
+ Keypair, LAMPORTS_PER_SOL, PublicKey, RpcResponseAndContext, SignatureResult, SignatureStatus,
+ SimulatedTransactionResponse, SystemProgram,
+ Transaction, TransactionError,
+ TransactionInstruction,
+ TransactionSignature
+} from "@solana/web3.js";
+import {WalletContextState} from "@solana/wallet-adapter-react";
+import {ActionProtocol} from "../../models/action-protocol";
+import {
+ GOVERNANCE_PROGRAM_ID,
+ GOVERNANCE_PROGRAM_LOCALNET_ID,
+ USDC_DEVNET,
+ USDC_LOCALNET
+} from "../../models/constants";
+import {isNumber, isString} from "underscore";
+import {
+ GovernanceConfig, MintMaxVoteWeightSource,
+ VoteThresholdPercentage, withCreateGovernance, withCreateMintGovernance, withCreateRealm,
+ withDepositGoverningTokens,
+ withSetRealmAuthority
+} from "@tokr-labs/governance";
+import BN from "bn.js";
+import {generateSlug} from "random-word-slugs";
+import {sleep} from "@project-serum/common";
+import {
+ ASSOCIATED_TOKEN_PROGRAM_ID,
+ AuthorityType,
+ createAssociatedTokenAccountInstruction, createInitializeMintInstruction,
+ createMintToInstruction,
+ createSetAuthorityInstruction, getAssociatedTokenAddress, MintLayout, TOKEN_PROGRAM_ID
+} from "@solana/spl-token";
+
+export class CreateDaoAction implements ActionProtocol {
+
+ // ============================================================
+ // === Internal API ===========================================
+ // ============================================================
+
+ /**
+ * Constructor
+ * @param connection
+ * @param wallet
+ */
+ constructor(
+ private connection: Connection,
+ private wallet: WalletContextState
+ ) {
+ }
+
+ /**
+ * Create a dao based on the config passed
+ * @param config json object
+ */
+ async execute(config): Promise {
+
+ if (!this.validate(config)) {
+ throw new Error("validation failed")
+ }
+
+ console.log("Executing create dao action...")
+
+ const councilMint = Keypair.generate()
+ const lpMint = Keypair.generate()
+
+ const mintInstructions: TransactionInstruction[] = [];
+ const delegateInstructions: TransactionInstruction[] = [];
+ const realmInstructions: TransactionInstruction[] = [];
+ const treasuryInstructions: TransactionInstruction[] = [];
+
+ const instructionSet: TransactionInstruction[][] = [
+ mintInstructions,
+ delegateInstructions,
+ realmInstructions,
+ treasuryInstructions
+ ]
+
+ const addresses = await this.createInstructions(
+ instructionSet,
+ this.wallet.publicKey!,
+ this.wallet.publicKey!,
+ councilMint.publicKey,
+ lpMint.publicKey,
+ config
+ )
+
+ const transactionSignatures = await this.sendTransactions(
+ instructionSet,
+ [[councilMint, lpMint], [], [], []]
+ )
+
+ console.log("Transactions:");
+ console.log(transactionSignatures);
+
+ console.log("Addresses:")
+ console.log("realmAddress", addresses.realmAddress?.toBase58() ?? "unknown");
+ console.log("councilGovernance", addresses.councilGovernance?.toBase58() ?? "unknown");
+ console.log("usdcTreasury", addresses.usdcTreasury?.toBase58() ?? "unknown");
+ console.log("lpGovernance", addresses.lpGovernance?.toBase58() ?? "unknown");
+ console.log("lpStockTreasury", addresses.lpStockTreasury?.toBase58() ?? "unknown");
+
+ }
+
+ /**
+ * Simulate the deposit liquidity transaction
+ */
+ async simulate(): Promise {
+
+ //
+ // console.log("Simulating transactions...")
+ //
+ // const simulatedSigner = Keypair.generate()
+ //
+ // const instructionSet: TransactionInstruction[][] = []
+ // const signerSet: Keypair[][] = [[delegateMint, distributionMint, lpMint, simulatedSigner], [simulatedSigner], [simulatedSigner], [simulatedSigner]]
+ // const transactions: Transaction[] = []
+ //
+ // // @TODO - create instructions
+ //
+ // const block = await this.connection.getLatestBlockhash(this.connection.commitment)
+ //
+ // for (let i = 0; i < instructionSet.length; i++) {
+ //
+ // const instructions = instructionSet[i]
+ // const signers = signerSet[i]
+ //
+ // if (instructions.length === 0) {
+ // continue
+ // }
+ //
+ // const transaction = new Transaction({recentBlockhash: block.blockhash})
+ // transaction.feePayer = simulatedSigner.publicKey
+ // transaction.add(...instructions);
+ //
+ // if (signers.length > 0) {
+ // transaction.partialSign(...signers)
+ // }
+ //
+ // transactions.push(transaction)
+ //
+ // }
+ //
+ // const simulatedTransactionPromises = transactions.map((transaction, index) => {
+ // const signers = signerSet[index].length > 0 ? signerSet[index] : [];
+ // return this.connection.simulateTransaction(transaction, [...signers, simulatedSigner])
+ // })
+ //
+ // await Promise.all(simulatedTransactionPromises)
+ //
+ // console.log("Simulation complete.");
+ //
+
+ }
+
+ // ============================================================
+ // === Private API ============================================
+ // ============================================================
+
+ // Private Methods
+
+ /**
+ *
+ * @param instructionSet
+ * @param signerSet
+ * @private
+ */
+ private async sendTransactions(
+ instructionSet: TransactionInstruction[][],
+ signerSet: Keypair[][]
+ ): Promise {
+
+ if (this.wallet === undefined || !this.wallet.connected) {
+ throw new Error("Wallet not connected")
+ }
+
+ console.log("Sending transactions...")
+
+ const block = await this.connection.getLatestBlockhash(this.connection.commitment)
+
+ const transactions: Transaction[] = []
+
+ for (let i = 0; i < instructionSet.length; i++) {
+
+ const instructions = instructionSet[i]
+ const signers = signerSet[i]
+
+ if (instructions.length === 0) {
+ continue
+ }
+
+ const transaction = new Transaction({recentBlockhash: block.blockhash})
+ transaction.feePayer = this.wallet.publicKey!
+ transaction.add(...instructions);
+
+ if (signers.length > 0) {
+ transaction.partialSign(...signers)
+ }
+
+ transactions.push(transaction)
+
+ }
+
+ const signedTransactions = await this.wallet!.signAllTransactions!(transactions)
+
+ const txsigs: TransactionSignature[] = [];
+
+ await signedTransactions.reduce(
+ (p, tx) => p.then(() => {
+ return this.sendSignedTransaction(tx).then(value => txsigs.push(value))
+ }),
+ Promise.resolve()
+ )
+
+ console.log("Transactions sent.")
+
+ return txsigs;
+
+ }
+
+ /**
+ *
+ * @param transaction
+ * @private
+ */
+ private async sendSignedTransaction(transaction: Transaction): Promise {
+
+ const rawTransaction = transaction.serialize()
+
+ const signature = await this.connection.sendRawTransaction(
+ rawTransaction,
+ {
+ skipPreflight: true
+ }
+ )
+
+ await this.confirmTransaction(signature)
+
+ await sleep(500)
+
+ return signature
+
+ }
+
+ /**
+ *
+ * @param instructionSet
+ * @param payer
+ * @param delegate
+ * @param lpMint
+ * @param councilMint
+ * @param config
+ * @private
+ */
+ private async createInstructions(
+ instructionSet: TransactionInstruction[][],
+ payer: PublicKey,
+ delegate: PublicKey,
+ councilMint: PublicKey,
+ lpMint: PublicKey,
+ config
+ ): Promise<{
+ realmAddress?: PublicKey,
+ councilGovernance?: PublicKey,
+ lpGovernance?: PublicKey,
+ usdcTreasury?: PublicKey,
+ lpStockTreasury?: PublicKey
+ }> {
+
+ console.log("Creating instructions...")
+
+ const maxRaise = config.details.maxRaise > 0 ? config.details.maxRaise : 1;
+
+ await this.createMintInstructions(instructionSet[0], this.wallet.publicKey!, lpMint)
+ await this.createMintInstructions(instructionSet[0], this.wallet.publicKey!, councilMint)
+
+ await this.createDelegateInstructions(
+ instructionSet[1],
+ payer,
+ councilMint,
+ delegate
+ )
+
+ const {
+ realmAddress,
+ councilGovernance,
+ lpGovernance,
+ } = await this.createRealmInstructions(
+ instructionSet[2],
+ GOVERNANCE_PROGRAM_ID,
+ payer,
+ delegate,
+ lpMint,
+ councilMint,
+ config
+ )
+
+ const {
+ usdcTreasury,
+ lpStockTreasury
+ } = await this.createTreasuryInstructions(
+ instructionSet[3],
+ councilMint,
+ lpMint,
+ councilGovernance!,
+ maxRaise
+ )
+
+ let totalInstructions = 0
+
+ instructionSet.forEach(set => {
+ totalInstructions += set.length;
+ })
+
+ console.log(`Total Instructions: ${totalInstructions}`);
+
+ return {
+ realmAddress,
+ councilGovernance,
+ lpStockTreasury,
+ lpGovernance,
+ usdcTreasury,
+ }
+
+ }
+
+ /**
+ *
+ * @param instructions
+ * @param payer
+ * @param mint
+ * @private
+ */
+ private async createMintInstructions(
+ instructions: TransactionInstruction[],
+ payer: PublicKey,
+ mint: PublicKey
+ ): Promise {
+
+ const rent = await this.connection.getMinimumBalanceForRentExemption(
+ MintLayout.span
+ )
+
+ // create lp token account for mint
+
+ instructions.push(
+ SystemProgram.createAccount({
+ fromPubkey: payer,
+ newAccountPubkey: mint,
+ lamports: rent,
+ space: MintLayout.span,
+ programId: TOKEN_PROGRAM_ID
+ })
+ )
+
+ // create lp mint
+
+ instructions.push(
+ createInitializeMintInstruction(
+ mint,
+ 0,
+ payer,
+ null
+ )
+ )
+
+ }
+
+ /**
+ *
+ * @param instructions
+ * @param payer
+ * @param councilMint
+ * @param delegate
+ * @private
+ */
+ private async createDelegateInstructions(
+ instructions: TransactionInstruction[],
+ payer: PublicKey,
+ councilMint: PublicKey,
+ delegate: PublicKey
+ ): Promise {
+
+ const delegateAta = await getAssociatedTokenAddress(
+ councilMint,
+ delegate
+ )
+
+ // create the associated token account for the delegate
+
+ instructions.push(
+ createAssociatedTokenAccountInstruction(
+ payer,
+ delegateAta,
+ delegate,
+ councilMint,
+ TOKEN_PROGRAM_ID,
+ ASSOCIATED_TOKEN_PROGRAM_ID
+ )
+ )
+
+ // mint 1 delegate token to the delegate
+
+ instructions.push(
+ createMintToInstruction(
+ councilMint,
+ delegateAta,
+ payer,
+ 1
+ )
+ )
+
+ }
+
+ /**
+ *
+ * @param instructions
+ * @param governanceProgramId
+ * @param payer
+ * @param delegate
+ * @param lpMint
+ * @param councilMint
+ * @param config
+ * @private
+ */
+ private async createRealmInstructions(
+ instructions: TransactionInstruction[],
+ governanceProgramId: PublicKey,
+ payer: PublicKey,
+ delegate: PublicKey,
+ lpMint: PublicKey,
+ councilMint: PublicKey,
+ config
+ ): Promise<{
+ realmAddress: PublicKey,
+ councilGovernance?: PublicKey,
+ lpGovernance?: PublicKey
+ }> {
+
+ const name = config.name !== "" ? config.name : config.name = generateSlug(3, {format: "title"});
+
+ const realmConfig = new GovernanceConfig({
+ voteThresholdPercentage: new VoteThresholdPercentage({
+ value: config.governance.voteThresholdPercentage,
+ }),
+ minCommunityTokensToCreateProposal: new BN(config.governance.minCommunityTokensToCreateProposal),
+ minInstructionHoldUpTime: config.governance.minInstructionHoldUpTime,
+ maxVotingTime: config.governance.maxVotingTime,
+ voteTipping: config.governance.voteTipping,
+ proposalCoolOffTime: config.governance.proposalCoolOffTime,
+ minCouncilTokensToCreateProposal: new BN(config.governance.minCouncilTokensToCreateProposal),
+ });
+
+ const delegateAta = await getAssociatedTokenAddress(
+ councilMint,
+ delegate
+ )
+
+ const realmAddress = await withCreateRealm(
+ instructions,
+ governanceProgramId,
+ 2,
+ name,
+ payer,
+ lpMint,
+ payer,
+ councilMint,
+ MintMaxVoteWeightSource.FULL_SUPPLY_FRACTION,
+ new BN(LAMPORTS_PER_SOL * 1000000)
+ )
+
+ const [tokenOwnerRecord] = await PublicKey.findProgramAddress(
+ [
+ governanceProgramId.toBuffer(),
+ realmAddress.toBuffer(),
+ delegate.toBuffer(),
+ payer.toBuffer(),
+ ],
+ governanceProgramId,
+ );
+
+ // create the lp governance for the realm
+
+ const councilGovernance = await withCreateGovernance(
+ instructions,
+ governanceProgramId,
+ 2,
+ realmAddress,
+ undefined,
+ realmConfig,
+ tokenOwnerRecord,
+ payer,
+ payer,
+ )
+
+ const lpGovernance = await withCreateGovernance(
+ instructions,
+ governanceProgramId,
+ 2,
+ realmAddress,
+ undefined,
+ realmConfig,
+ tokenOwnerRecord,
+ payer,
+ payer,
+ )
+
+ // transfer authority of the realm from the owner to the lp governance
+
+ withSetRealmAuthority(
+ instructions,
+ governanceProgramId,
+ 2,
+ realmAddress,
+ payer,
+ councilGovernance,
+ 1
+ )
+
+ // deposit the delegate's delegate token into the realm for them
+
+ if (payer === delegate) {
+
+ await withDepositGoverningTokens(
+ instructions,
+ governanceProgramId,
+ 2, // why does program 2 work and not program 1
+ realmAddress,
+ delegateAta,
+ councilMint,
+ delegate,
+ delegate,
+ delegate,
+ new BN(1)
+ )
+
+ }
+
+ return {
+ realmAddress,
+ councilGovernance,
+ lpGovernance
+ }
+
+ }
+
+ /**
+ *
+ * @param instructions
+ * @param councilMint
+ * @param lpMint
+ * @param councilGovernance
+ * @param maxRaise
+ * @private
+ */
+ private async createTreasuryInstructions(
+ instructions: TransactionInstruction[],
+ councilMint: PublicKey,
+ lpMint: PublicKey,
+ councilGovernance: PublicKey,
+ maxRaise: number
+ ): Promise<{
+ usdcTreasury?: PublicKey,
+ lpStockTreasury?: PublicKey
+ }> {
+
+ const usdcTreasury = await this.createTreasuryAccountInstructions(
+ instructions,
+ this.wallet.publicKey!,
+ USDC_DEVNET,
+ councilGovernance
+ )
+
+ const lpStockTreasury = await this.createTreasuryAccountInstructions(
+ instructions,
+ this.wallet.publicKey!,
+ lpMint,
+ councilGovernance
+ )
+
+ instructions.push(
+ createMintToInstruction(
+ lpMint, // mint
+ lpStockTreasury, // destination
+ this.wallet.publicKey!, // authority
+ maxRaise // amount
+ )
+ )
+
+ instructions.push(
+ createSetAuthorityInstruction(
+ lpMint,
+ this.wallet.publicKey!,
+ AuthorityType.MintTokens,
+ null
+ )
+ )
+
+ instructions.push(
+ createSetAuthorityInstruction(
+ councilMint,
+ this.wallet.publicKey!,
+ AuthorityType.MintTokens,
+ councilGovernance
+ )
+ )
+
+ return {
+ usdcTreasury,
+ lpStockTreasury
+ }
+
+ }
+
+ /**
+ *
+ * @param instructions
+ * @param payer
+ * @param mint
+ * @param governance
+ * @private
+ */
+ private async createTreasuryAccountInstructions(
+ instructions: TransactionInstruction[],
+ payer: PublicKey,
+ mint: PublicKey,
+ governance: PublicKey
+ ): Promise {
+
+ const treasuryAta = await getAssociatedTokenAddress(
+ mint,
+ governance,
+ true,
+ )
+
+ instructions.push(
+ createAssociatedTokenAccountInstruction(
+ payer,
+ treasuryAta,
+ governance,
+ mint
+ )
+ )
+
+ return treasuryAta
+ }
+
+ /**
+ *
+ * @param config
+ * @private
+ */
+ private validate(config): boolean {
+
+ return true
+
+ // return !!(
+ // isString(config.name) &&
+ // isString(config.governanceProgramId) &&
+ // isString(config.usdcMint) &&
+ // isNumber(config.governance.voteThresholdPercentage) &&
+ // isNumber(config.governance.minCommunityTokensToCreateProposal) &&
+ // isNumber(config.governance.minInstructionHoldUpTime) &&
+ // isNumber(config.governance.maxVotingTime) &&
+ // isNumber(config.governance.voteTipping) &&
+ // isNumber(config.governance.proposalCoolOffTime) &&
+ // isNumber(config.governance.minCouncilTokensToCreateProposal)
+ // );
+ }
+
+ /**
+ *
+ * @param signature
+ * @private
+ */
+ private async confirmTransaction(signature: TransactionSignature): Promise {
+
+ console.log(`Confirming transaction '${signature}'...`)
+
+ let signatureResult: RpcResponseAndContext<(SignatureResult)> = {
+ context: {
+ slot: 0
+ },
+ value: {err: null}
+ }
+
+ let confirmed = false
+ const blockhash = await this.connection.getLatestBlockhash();
+
+ while (!confirmed) {
+
+ signatureResult = await this.connection.confirmTransaction(
+ {
+ signature: signature,
+ ...blockhash
+ },"singleGossip"
+ )
+
+ if (signatureResult && signatureResult.value !== null) {
+ confirmed = true
+ }
+
+ await sleep(150)
+
+ }
+
+ if (signatureResult?.value.err !== null) {
+ console.log("Errored Signature Result:");
+ console.log(signatureResult);
+ throw new Error(`Something went wrong. Please try again. ${JSON.stringify(signatureResult?.value.err) ?? "unknown error"}`)
+ }
+
+ return Promise.resolve()
+
+ }
+
+}
+
+
diff --git a/src/themes.tsx b/src/themes.tsx
index e4f2c29..6782c33 100644
--- a/src/themes.tsx
+++ b/src/themes.tsx
@@ -76,7 +76,9 @@ export const lightTheme = createTheme({
)`,
background: "#f8f5f6",
purple100: "#0C0223",
- purple200: "#170037"
+ purple200: "#170037",
+ green100: "#4ad47b",
+ gray100: "#BCBCBC",
},
fonts: {
sans: "Montserrat, sans-serif",
@@ -104,7 +106,9 @@ export const darkTheme = createTheme({
)`,
background: "$black",
purple100: "#0C0223",
- purple200: "#170037"
+ purple200: "#170037",
+ green100: "#4ad47b",
+ gray100: "#BCBCBC",
},
fonts: {
sans: "Montserrat, sans-serif",