diff --git a/.gitignore b/.gitignore index d45c861..1ca8e07 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ npm-debug.log* .openzeppelin /backup + +/typechain diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index 96b640d..0000000 --- a/babel.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - presets: [ - '@babel/preset-env', - ['@babel/preset-react', {runtime: 'automatic'}], - ], -}; \ No newline at end of file diff --git a/babel.config.json b/babel.config.json new file mode 100644 index 0000000..7a73a41 --- /dev/null +++ b/babel.config.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/contracts/PointSocial.sol b/contracts/PointSocial.sol index 865f2a4..f498ff7 100644 --- a/contracts/PointSocial.sol +++ b/contracts/PointSocial.sol @@ -3,6 +3,8 @@ pragma solidity >=0.8.0; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; + import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; @@ -12,6 +14,9 @@ import "point-contract-manager/contracts/IIdentity.sol"; contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeable { using Counters for Counters.Counter; + + /************************* STORAGE LAYOUT START *************************/ + Counters.Counter internal _postIds; Counters.Counter internal _commentIds; Counters.Counter internal _likeIds; @@ -108,8 +113,7 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus Counters.Counter internal _dislikeIds; mapping(uint256 => uint256[]) public dislikeIdsByPost; mapping(address => uint256[]) public dislikeIdsByUser; - mapping(address => mapping(uint256 => uint256)) - public dislikeIdByUserAndPost; + mapping(address => mapping(uint256 => uint256)) public dislikeIdByUserAndPost; mapping(uint256 => Dislike) public dislikeById; struct PostWithMetadata { @@ -123,10 +127,45 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus uint256 dislikesCount; bool liked; bool disliked; + bool flagged; + } + + /* + * Follow functions storage + */ + using EnumerableSet for EnumerableSet.AddressSet; + + struct FollowConnections { + EnumerableSet.AddressSet following; + EnumerableSet.AddressSet followers; + EnumerableSet.AddressSet blocked; + } + + mapping(address => FollowConnections) internal _followConnectionsByUser; + + enum FollowAction { + Follow, + UnFollow, + Block, + UnBlock + } + + event FollowEvent( + address indexed from, + address indexed to, + FollowAction action); + + enum FeedType { + Discover, + Follow, + Fresh, + Top } + /************************* STORAGE LAYOUT END *************************/ + modifier postExists(uint256 _postId) { - require(postById[_postId].from != address(0), "Post does not exist"); + require(postById[_postId].from != address(0), "ERROR_POST_DOES_NOT_EXISTS"); _; } @@ -135,7 +174,12 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus "ERROR_NOT_DEPLOYER" ); _; - } + } + + modifier onlyMigrator() { + require(msg.sender == _migrator, "ERROR_NOT_MIGRATOR"); + _; + } function initialize( address identityContractAddr, @@ -204,8 +248,7 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus uint256 postId, bytes32 contents, bytes32 image - ) public whenNotPaused { - require(postById[postId].createdAt != 0, "ERROR_POST_DOES_NOT_EXISTS"); + ) public whenNotPaused postExists(postId) { require( msg.sender == postById[postId].from, "ERROR_CANNOT_EDIT_OTHERS_POSTS" @@ -223,8 +266,7 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus ); } - function deletePost(uint256 postId) public whenNotPaused { - require(postById[postId].createdAt != 0, "ERROR_POST_DOES_NOT_EXISTS"); + function deletePost(uint256 postId) public whenNotPaused postExists(postId) { require( msg.sender == postById[postId].from, "ERROR_CANNOT_DELETE_OTHERS_POSTS" @@ -245,13 +287,8 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus ); } - function flagPost(uint256 postId) public whenNotPaused { - require(IIdentity(_identityContractAddr).isIdentityDeployer(_identityHandle, msg.sender), - "ERROR_PERMISSION_DENIED"); - require(postById[postId].createdAt != 0, "ERROR_POST_DOES_NOT_EXISTS"); - + function flagPost(uint256 postId) public onlyDeployer whenNotPaused postExists(postId) { postIsFlagged[postId] = !postIsFlagged[postId]; - emit StateChange(postId, msg.sender, block.timestamp, Component.Post, Action.Flag); } @@ -264,30 +301,73 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus } function getAllPostsLength() public view returns (uint256) { - uint256 length = 0; - for (uint256 i = 0; i < postIds.length; i++) { - if (postById[postIds[i]].createdAt > 0) { - length++; - } + return postIds.length; + } + + function getLastPostId() public view returns (uint256) { + return (postIds.length > 0)? postIds[postIds.length-1] : 0; + } + + function _includePost(uint256 postId, FeedType _type) internal view returns (bool) { + Post memory p = postById[postId]; + if (_type == FeedType.Discover) { + return (!postIsFlagged[postId] && /* Filter flagged posts */ + !(isBlocked(msg.sender, p.from) /* Filter blocked users */ + || isBlocked(p.from, msg.sender)) && /* Filter blocked users */ + !(p.from == msg.sender) //&& /* Filter own posts */ + //!isFollowing(msg.sender, p.from) /* Filter following users */ + ); + } + else if (_type == FeedType.Follow) { + return (isFollowing(msg.sender, p.from)); /* Filter following users */ + } + else if (_type == FeedType.Top) { + return (!postIsFlagged[postId] && /* Filter flagged posts */ + !(isBlocked(msg.sender, p.from) + || isBlocked(p.from, msg.sender)) && /* Filter blocked users */ + !(p.likesCount == 0)); /* Filter unvoted posts */ + } + else { + return (!(isBlocked(msg.sender, p.from) /* Filter blocked users */ + || isBlocked(p.from, msg.sender))); } - return length; } - function getPaginatedPosts(uint256 cursor, uint256 howMany) + function getPaginatedPosts(uint256 _cursor, uint256 _howMany, FeedType _type) public view returns (PostWithMetadata[] memory) { - uint256 length = howMany; - if (length > postIds.length - cursor) { - length = postIds.length - cursor; + require(_howMany > 0, "ERROR_INVALID_AMOUNT"); + require((_cursor > 0) && (_cursor <= postIds.length), "ERROR_INVALID_CURSOR"); + + uint256 length = _howMany; + if (length > _cursor) { + length = _cursor; } - PostWithMetadata[] memory postsWithMetadata = new PostWithMetadata[](length); - for (uint256 i = length; i > 0; i--) { - postsWithMetadata[length - i] = _getPostWithMetadata(postIds[postIds.length - cursor - i]); + PostWithMetadata[] memory posts = new PostWithMetadata[](length); + + //Do not check when user does not have followings + if ((_type == FeedType.Follow) && + (EnumerableSet.length(_followConnectionsByUser[msg.sender].following) == 0)) { + return posts; } - return postsWithMetadata; + + uint256 j = 0; + uint256 i = _cursor; + + do { + i--; + uint256 id = postIds[i]; + if (_includePost(id, _type)) { + posts[j] = _getPostWithMetadata(id); + j++; + } + } + while(i > 0 && j < length); + + return posts; } function getAllPostsByOwner(address owner) @@ -295,11 +375,16 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus view returns (PostWithMetadata[] memory) { - PostWithMetadata[] memory postsWithMetadata = new PostWithMetadata[](postIdsByOwner[owner].length); - for (uint256 i = 0; i < postIdsByOwner[owner].length; i++) { - postsWithMetadata[i] = _getPostWithMetadata(postIdsByOwner[owner][i]); + if (isBlocked(msg.sender, owner) || isBlocked(owner, msg.sender)) { + return new PostWithMetadata[](0); + } + else { + PostWithMetadata[] memory postsWithMetadata = new PostWithMetadata[](postIdsByOwner[owner].length); + for (uint256 i = 0; i < postIdsByOwner[owner].length; i++) { + postsWithMetadata[i] = _getPostWithMetadata(postIdsByOwner[owner][i]); + } + return postsWithMetadata; } - return postsWithMetadata; } function getAllPostsByOwnerLength(address owner) @@ -328,7 +413,8 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus post.commentsCount, getPostDislikesQty(_postId), checkLikeToPost(_postId), - checkDislikeToPost(_postId) + checkDislikeToPost(_postId), + postIsFlagged[_postId] ); return postWithMetadata; } @@ -645,6 +731,10 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus return false; } + /********************************************************************** + * User Profile Functions + ***********************************************************************/ + function setProfile( bytes32 name_, bytes32 location_, @@ -664,7 +754,9 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus return profileByOwner[id_]; } - // Data Migrator Functions - only callable by _migrator + /********************************************************************** + * Data Migrator Functions - only callable by _migrator + ***********************************************************************/ function add( uint256 id, @@ -673,8 +765,7 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus bytes32 image, uint16 likesCount, uint256 createdAt - ) public { - require(msg.sender == _migrator, "Access Denied"); + ) public onlyMigrator { Post memory _post = Post({ id: id, @@ -706,8 +797,7 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus address author, bytes32 contents, uint256 createdAt - ) public { - require(msg.sender == _migrator, "Access Denied"); + ) public onlyMigrator { Comment memory _comment = Comment({ id: id, @@ -738,8 +828,7 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus bytes32 about, bytes32 avatar, bytes32 banner - ) public { - require(msg.sender == _migrator, "Access Denied"); + ) public onlyMigrator { profileByOwner[user].displayName = name; profileByOwner[user].displayLocation = location; @@ -750,6 +839,85 @@ contract PointSocial is Initializable, UUPSUpgradeable, OwnableUpgradeable, Paus emit ProfileChange(user, block.timestamp); } + /********************************************************************** + * Follow functions + ***********************************************************************/ + + modifier onlyMutuals (address _user) { + require(isFollowing(msg.sender, _user), "ERROR_NOT_MUTUAL"); + require(isFollowing(_user, msg.sender), "ERROR_NOT_MUTUAL"); + _; + } + + modifier onlyFollowers (address _user) { + require((msg.sender == _user) || isFollowing(msg.sender, _user), "ERROR_NOT_FOLLOWING"); + _; + } + + modifier notBlocked (address _user) { + require(!isBlocked(msg.sender, _user), "ERROR_USER_BLOCKED"); + require(!isBlocked(_user, msg.sender), "ERROR_USER_BLOCKED"); + _; + } + + function followUser(address _user) public notBlocked(_user) { + EnumerableSet.add(_followConnectionsByUser[msg.sender].following, _user); + EnumerableSet.add(_followConnectionsByUser[_user].followers, msg.sender); + emit FollowEvent(msg.sender, _user, FollowAction.Follow); + } + + function unfollowUser(address _user) public { + EnumerableSet.remove(_followConnectionsByUser[msg.sender].following, _user); + EnumerableSet.remove(_followConnectionsByUser[_user].followers, msg.sender); + emit FollowEvent(msg.sender, _user, FollowAction.UnFollow); + } + + function isFollowing(address _owner, address _user) public view returns (bool) { + return EnumerableSet.contains(_followConnectionsByUser[_owner].following, _user); + } + + function followingList(address _user) public onlyFollowers(_user) view returns (address[] memory) { + return EnumerableSet.values(_followConnectionsByUser[_user].following); + } + + function followingCount(address _user) public view returns (uint256) { + return EnumerableSet.length(_followConnectionsByUser[_user].following); + } + + function followersList(address _user) public onlyFollowers(_user) view returns (address[] memory) { + return EnumerableSet.values(_followConnectionsByUser[_user].followers); + } + + function followersCount(address _user) public view returns (uint256) { + return EnumerableSet.length(_followConnectionsByUser[_user].followers); + } + + function blockUser(address _user) public { + EnumerableSet.remove(_followConnectionsByUser[msg.sender].following, _user); + EnumerableSet.remove(_followConnectionsByUser[msg.sender].followers, _user); + EnumerableSet.remove(_followConnectionsByUser[_user].following, msg.sender); + EnumerableSet.remove(_followConnectionsByUser[_user].followers, msg.sender); + EnumerableSet.add(_followConnectionsByUser[msg.sender].blocked, _user); + emit FollowEvent(msg.sender, _user, FollowAction.Block); + } + + function unBlockUser(address _user) public { + EnumerableSet.remove(_followConnectionsByUser[msg.sender].blocked, _user); + emit FollowEvent(msg.sender, _user, FollowAction.UnBlock); + } + + function isBlocked(address _owner, address _user) public view returns (bool) { + return EnumerableSet.contains(_followConnectionsByUser[_owner].blocked, _user); + } + + function blockList() public view returns (address[] memory) { + return EnumerableSet.values(_followConnectionsByUser[msg.sender].blocked); + } + + /********************************************************************** + * Like migration functions + ***********************************************************************/ + function addLike( uint256 _id, address _from, diff --git a/hardhat.config.ts b/hardhat.config.ts index 3ca9f86..20a3919 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -5,6 +5,7 @@ import '@typechain/hardhat'; import '@nomiclabs/hardhat-waffle'; import '@nomiclabs/hardhat-ethers'; import 'hardhat-gas-reporter'; +import "hardhat-contract-sizer"; import 'solidity-coverage'; import '@openzeppelin/hardhat-upgrades'; import './tasks/social-migrator'; diff --git a/package-lock.json b/package-lock.json index 7e5cbe9..4258083 100644 --- a/package-lock.json +++ b/package-lock.json @@ -69,6 +69,7 @@ "ethereumjs-wallet": "^1.0.2", "ethers": "^5.5.4", "hardhat": "^2.9.8", + "hardhat-contract-sizer": "^2.6.1", "hardhat-gas-reporter": "^1.0.8", "https-proxy-agent": "^5.0.1", "identity-obj-proxy": "^3.0.0", @@ -2025,11 +2026,21 @@ "node": ">=0.1.95" } }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@cspotcode/source-map-support": { "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 +2052,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" @@ -4238,175 +4249,6 @@ "hardhat": "^2.0.0" } }, - "node_modules/@nomiclabs/hardhat-etherscan": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.0.tgz", - "integrity": "sha512-JroYgfN1AlYFkQTQ3nRwFi4o8NtZF7K/qFR2dxDUgHbCtIagkUseca9L4E/D2ScUm4XT40+8PbCdqZi+XmHyQA==", - "dev": true, - "peer": true, - "dependencies": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/address": "^5.0.2", - "cbor": "^5.0.2", - "chalk": "^2.4.2", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "lodash": "^4.17.11", - "semver": "^6.3.0", - "table": "^6.8.0", - "undici": "^5.4.0" - }, - "peerDependencies": { - "hardhat": "^2.0.4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "peer": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/cbor": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", - "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", - "dev": true, - "peer": true, - "dependencies": { - "bignumber.js": "^9.0.1", - "nofilter": "^1.0.4" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "peer": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "peer": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "peer": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/nofilter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", - "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "peer": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/@nomiclabs/hardhat-waffle": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.3.tgz", @@ -6519,25 +6361,6 @@ "node": ">=6" } }, - "node_modules/@testing-library/dom": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.17.1.tgz", - "integrity": "sha512-KnH2MnJUzmFNPW6RIKfd+zf2Wue8mEKX0M3cpX6aKl5ZXrJM1/c/Pc8c2xDNYQCnJO48Sm5ITbMXgqTr3h4jxQ==", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@testing-library/jest-dom": { "version": "5.16.2", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz", @@ -6753,25 +6576,25 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "devOptional": true + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "devOptional": true + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "devOptional": true + "dev": true }, "node_modules/@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "devOptional": true + "dev": true }, "node_modules/@typechain/ethers-v5": { "version": "7.2.0", @@ -6870,17 +6693,6 @@ "@types/node": "*" } }, - "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, - "peer": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, "node_modules/@types/chai": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", @@ -6896,16 +6708,6 @@ "@types/node": "*" } }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, - "peer": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/dotenv": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-8.2.0.tgz", @@ -6930,31 +6732,6 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==" }, - "node_modules/@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dev": true, - "peer": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.30", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz", - "integrity": "sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ==", - "dev": true, - "peer": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, "node_modules/@types/form-data": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", @@ -7067,13 +6844,6 @@ "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", "dev": true }, - "node_modules/@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", - "dev": true, - "peer": true - }, "node_modules/@types/mime-types": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.1.tgz", @@ -7147,13 +6917,6 @@ "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", "dev": true }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true, - "peer": true - }, "node_modules/@types/react": { "version": "17.0.39", "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz", @@ -7198,17 +6961,6 @@ "@types/node": "*" } }, - "node_modules/@types/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", - "dev": true, - "peer": true, - "dependencies": { - "@types/mime": "*", - "@types/node": "*" - } - }, "node_modules/@types/sinon": { "version": "10.0.11", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.11.tgz", @@ -8037,7 +7789,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/argparse": { "version": "1.0.10", @@ -9413,7 +9165,7 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "devOptional": true, + "dev": true, "hasInstallScript": true, "dependencies": { "node-gyp-build": "^4.3.0" @@ -10740,7 +10492,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-spawn": { "version": "6.0.5", @@ -25109,6 +24861,34 @@ "chai": "^4.2.0" } }, + "node_modules/hardhat-contract-sizer": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.6.1.tgz", + "integrity": "sha512-b8wS7DBvyo22kmVwpzstAQTdDCThpl/ySBqZh5ga9Yxjf61/uTL12TEg5nl7lDeWy73ntEUzxMwY6XxbQEc2wA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "cli-table3": "^0.6.0" + }, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat-contract-sizer/node_modules/cli-table3": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", + "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, "node_modules/hardhat-gas-reporter": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz", @@ -29106,7 +28886,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", @@ -34420,6 +34200,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "dev": true, "bin": { "prettier": "bin-prettier.js" }, @@ -35398,19 +35179,6 @@ "node": ">=0.10.0" } }, - "node_modules/react-scripts/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "optional": true, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/react-shallow-renderer": { "version": "16.15.0", "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", @@ -40235,7 +40003,7 @@ "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "devOptional": true, + "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -40278,7 +40046,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" } @@ -40287,7 +40055,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" } @@ -40534,6 +40302,7 @@ "version": "4.7.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -40924,7 +40693,7 @@ "version": "5.0.9", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", - "devOptional": true, + "dev": true, "hasInstallScript": true, "dependencies": { "node-gyp-build": "^4.3.0" @@ -41005,7 +40774,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": "7.1.2", @@ -44067,7 +43836,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" } @@ -45400,11 +45169,18 @@ "minimist": "^1.2.0" } }, + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true + }, "@cspotcode/source-map-support": { "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" }, @@ -45413,7 +45189,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" @@ -45805,8 +45581,7 @@ "version": "6.0.7", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==", - "dev": true, - "requires": {} + "dev": true }, "typechain": { "version": "3.0.0", @@ -46261,8 +46036,7 @@ "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true, - "requires": {} + "dev": true } } }, @@ -46874,8 +46648,7 @@ "@material-ui/types": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz", - "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==", - "requires": {} + "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==" }, "@material-ui/utils": { "version": "4.11.3", @@ -47012,146 +46785,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.6.tgz", "integrity": "sha512-q2Cjp20IB48rEn2NPjR1qxsIQBvFVYW9rFRCFq+bC4RUrn1Ljz3g4wM8uSlgIBZYBi2JMXxmOzFqHraczxq4Ng==", - "dev": true, - "requires": {} - }, - "@nomiclabs/hardhat-etherscan": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.0.tgz", - "integrity": "sha512-JroYgfN1AlYFkQTQ3nRwFi4o8NtZF7K/qFR2dxDUgHbCtIagkUseca9L4E/D2ScUm4XT40+8PbCdqZi+XmHyQA==", - "dev": true, - "peer": true, - "requires": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/address": "^5.0.2", - "cbor": "^5.0.2", - "chalk": "^2.4.2", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "lodash": "^4.17.11", - "semver": "^6.3.0", - "table": "^6.8.0", - "undici": "^5.4.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "peer": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "cbor": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", - "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", - "dev": true, - "peer": true, - "requires": { - "bignumber.js": "^9.0.1", - "nofilter": "^1.0.4" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "peer": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "peer": true - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "peer": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "peer": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "peer": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "nofilter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", - "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", - "dev": true, - "peer": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "peer": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "peer": true - } - } + "dev": true }, "@nomiclabs/hardhat-waffle": { "version": "2.0.3", @@ -48638,22 +48272,6 @@ "defer-to-connect": "^1.0.1" } }, - "@testing-library/dom": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.17.1.tgz", - "integrity": "sha512-KnH2MnJUzmFNPW6RIKfd+zf2Wue8mEKX0M3cpX6aKl5ZXrJM1/c/Pc8c2xDNYQCnJO48Sm5ITbMXgqTr3h4jxQ==", - "peer": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", - "pretty-format": "^27.0.2" - } - }, "@testing-library/jest-dom": { "version": "5.16.2", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz", @@ -48839,25 +48457,25 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "devOptional": true + "dev": true }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "devOptional": true + "dev": true }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "devOptional": true + "dev": true }, "@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "devOptional": true + "dev": true }, "@typechain/ethers-v5": { "version": "7.2.0", @@ -48873,8 +48491,7 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", - "dev": true, - "requires": {} + "dev": true } } }, @@ -48943,17 +48560,6 @@ "@types/node": "*" } }, - "@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, - "peer": true, - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, "@types/chai": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", @@ -48969,16 +48575,6 @@ "@types/node": "*" } }, - "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, - "peer": true, - "requires": { - "@types/node": "*" - } - }, "@types/dotenv": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-8.2.0.tgz", @@ -49002,31 +48598,6 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==" }, - "@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dev": true, - "peer": true, - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.30", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz", - "integrity": "sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ==", - "dev": true, - "peer": true, - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, "@types/form-data": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", @@ -49139,13 +48710,6 @@ "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", "dev": true }, - "@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", - "dev": true, - "peer": true - }, "@types/mime-types": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.1.tgz", @@ -49219,13 +48783,6 @@ "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", "dev": true }, - "@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true, - "peer": true - }, "@types/react": { "version": "17.0.39", "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz", @@ -49272,17 +48829,6 @@ "@types/node": "*" } }, - "@types/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", - "dev": true, - "peer": true, - "requires": { - "@types/mime": "*", - "@types/node": "*" - } - }, "@types/sinon": { "version": "10.0.11", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.11.tgz", @@ -49757,8 +49303,7 @@ "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-walk": { "version": "7.2.0", @@ -49834,14 +49379,12 @@ "ajv-errors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "requires": {} + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" }, "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==" }, "alphanum-sort": { "version": "1.0.2", @@ -49928,7 +49471,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "devOptional": true + "dev": true }, "argparse": { "version": "1.0.10", @@ -50496,8 +50039,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", @@ -51040,7 +50582,7 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "devOptional": true, + "dev": true, "requires": { "node-gyp-build": "^4.3.0" } @@ -52098,7 +51640,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-spawn": { "version": "6.0.5", @@ -52497,8 +52039,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.0.1.tgz", "integrity": "sha512-VNCHL364lh++/ono+S3j9NlUK+d97KNkxI77NlqZU2W3xd2/qmyN61dsa47pTpb55zuU4G4lI7qFjAXZJH1OAQ==", - "dev": true, - "requires": {} + "dev": true }, "csso": { "version": "4.2.0", @@ -53839,8 +53380,7 @@ "eslint-plugin-react-hooks": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz", - "integrity": "sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==", - "requires": {} + "integrity": "sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==" }, "eslint-plugin-testing-library": { "version": "3.10.2", @@ -63343,6 +62883,28 @@ } } }, + "hardhat-contract-sizer": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.6.1.tgz", + "integrity": "sha512-b8wS7DBvyo22kmVwpzstAQTdDCThpl/ySBqZh5ga9Yxjf61/uTL12TEg5nl7lDeWy73ntEUzxMwY6XxbQEc2wA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "cli-table3": "^0.6.0" + }, + "dependencies": { + "cli-table3": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", + "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", + "dev": true, + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + } + } + }, "hardhat-gas-reporter": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz", @@ -63818,8 +63380,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true, - "requires": {} + "dev": true }, "identity-obj-proxy": { "version": "3.0.0", @@ -65139,8 +64700,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": "26.0.0", @@ -66289,7 +65849,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", @@ -69365,29 +68925,25 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.2.tgz", "integrity": "sha512-6VQ3pYTsJHEsN2Bic88Aa7J/Brn4Bv8j/rqaFQZkH+pcVkKYwxCIvoMQkykEW7fBjmofdTnQgcivt5CCBJhtrg==", - "dev": true, - "requires": {} + "dev": true }, "postcss-discard-duplicates": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.2.tgz", "integrity": "sha512-LKY81YjUjc78p6rbXIsnppsaFo8XzCoMZkXVILJU//sK0DgPkPSpuq/cZvHss3EtdKvWNYgWzQL+wiJFtEET4g==", - "dev": true, - "requires": {} + "dev": true }, "postcss-discard-empty": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.2.tgz", "integrity": "sha512-SxBsbTjlsKUvZLL+dMrdWauuNZU8TBq5IOL/DHa6jBUSXFEwmDqeXRfTIK/FQpPTa8MJMxEHjSV3UbiuyLARPQ==", - "dev": true, - "requires": {} + "dev": true }, "postcss-discard-overridden": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.3.tgz", "integrity": "sha512-yRTXknIZA4k8Yo4FiF1xbsLj/VBxfXEWxJNIrtIy6HC9KQ4xJxcPtoaaskh6QptCGrrcGnhKsTsENTRPZOBu4g==", - "dev": true, - "requires": {} + "dev": true }, "postcss-double-position-gradients": { "version": "1.0.0", @@ -69864,8 +69420,7 @@ "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==", - "dev": true, - "requires": {} + "dev": true }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -69952,8 +69507,7 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.2.tgz", "integrity": "sha512-fEMhYXzO8My+gC009qDc/3bgnFP8Fv1Ic8uw4ec4YTlhIOw63tGPk1YFd7fk9bZUf1DAbkhiL/QPWs9JLqdF2g==", - "dev": true, - "requires": {} + "dev": true }, "postcss-normalize-display-values": { "version": "5.0.2", @@ -70403,7 +69957,8 @@ "prettier": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", - "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==" + "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "dev": true }, "prettier-plugin-solidity": { "version": "1.0.0-beta.19", @@ -70721,8 +70276,7 @@ "react-cool-inview": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/react-cool-inview/-/react-cool-inview-2.0.9.tgz", - "integrity": "sha512-r1FM52/xElWEDxOv61QSLS23NuzcuhaIkfNL/K4FQFZ+NN/O5vEx/HTdmR1r6SPqXSBhPy5lyD7+Ot3t8F9ttQ==", - "requires": {} + "integrity": "sha512-r1FM52/xElWEDxOv61QSLS23NuzcuhaIkfNL/K4FQFZ+NN/O5vEx/HTdmR1r6SPqXSBhPy5lyD7+Ot3t8F9ttQ==" }, "react-dev-utils": { "version": "11.0.4", @@ -71127,13 +70681,6 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "optional": true, - "peer": true } } }, @@ -71173,8 +70720,7 @@ "react-virtualized-auto-sizer": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.6.tgz", - "integrity": "sha512-7tQ0BmZqfVF6YYEWcIGuoR3OdYe8I/ZFbNclFlGOC3pMqunkYF/oL30NCjSGl9sMEb17AnzixDz98Kqc3N76HQ==", - "requires": {} + "integrity": "sha512-7tQ0BmZqfVF6YYEWcIGuoR3OdYe8I/ZFbNclFlGOC3pMqunkYF/oL30NCjSGl9sMEb17AnzixDz98Kqc3N76HQ==" }, "react-window": { "version": "1.8.7", @@ -71188,8 +70734,7 @@ "react-window-infinite-loader": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/react-window-infinite-loader/-/react-window-infinite-loader-1.0.7.tgz", - "integrity": "sha512-wg3LWkUpG21lhv+cZvNy+p0+vtclZw+9nP2vO6T9PKT50EN1cUq37Dq6FzcM38h/c2domE0gsUhb6jHXtGogAA==", - "requires": {} + "integrity": "sha512-wg3LWkUpG21lhv+cZvNy+p0+vtclZw+9nP2vO6T9PKT50EN1cUq37Dq6FzcM38h/c2domE0gsUhb6jHXtGogAA==" }, "read-pkg": { "version": "5.2.0", @@ -74939,7 +74484,7 @@ "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "devOptional": true, + "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -74960,13 +74505,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 }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "devOptional": true + "dev": true } } }, @@ -75132,8 +74677,7 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", - "dev": true, - "requires": {} + "dev": true }, "universalify": { "version": "0.1.2", @@ -75159,7 +74703,8 @@ "typescript": { "version": "4.7.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "dev": true }, "typical": { "version": "2.6.1", @@ -75453,7 +74998,7 @@ "version": "5.0.9", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", - "devOptional": true, + "dev": true, "requires": { "node-gyp-build": "^4.3.0" } @@ -75521,7 +75066,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": "7.1.2", @@ -77889,8 +77434,7 @@ "wouter": { "version": "2.7.5", "resolved": "https://registry.npmjs.org/wouter/-/wouter-2.7.5.tgz", - "integrity": "sha512-TOI9gD1wa7a8wW+lh3rjg0C+MjYGKMV3eC+++6D+7n1z36ZJIBPWe2G9Hs1jYNPsV7oKiPTI3UFC5TGhZjQfrQ==", - "requires": {} + "integrity": "sha512-TOI9gD1wa7a8wW+lh3rjg0C+MjYGKMV3eC+++6D+7n1z36ZJIBPWe2G9Hs1jYNPsV7oKiPTI3UFC5TGhZjQfrQ==" }, "wrap-ansi": { "version": "7.0.0", @@ -77931,8 +77475,7 @@ "ws": { "version": "7.5.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", - "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", - "requires": {} + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==" }, "xhr": { "version": "2.6.0", @@ -78104,7 +77647,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 0f731ad..6e8f4cd 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,7 @@ "ethereumjs-wallet": "^1.0.2", "ethers": "^5.5.4", "hardhat": "^2.9.8", + "hardhat-contract-sizer": "^2.6.1", "hardhat-gas-reporter": "^1.0.8", "https-proxy-agent": "^5.0.1", "identity-obj-proxy": "^3.0.0", diff --git a/src/components/comments/Comment.jsx b/src/components/comments/Comment.jsx deleted file mode 100644 index 2a46b6c..0000000 --- a/src/components/comments/Comment.jsx +++ /dev/null @@ -1,69 +0,0 @@ -import './comments.css' -import { format } from "timeago.js"; -import { useState } from "react"; -import { useAppContext } from '../../context/AppContext'; -import { Link } from "wouter"; -import CommentEditor from './CommentEditor'; - -import Snackbar from '@material-ui/core/Snackbar'; -import MuiAlert from '@material-ui/lab/Alert'; - -function Alert(props) { - return ; -} - -const Comment = ({ postId, comment, reloadComments }) => { - const { walletAddress } = useAppContext(); - const [editComment, setEditComment] = useState(false); - const [alert, setAlert] = useState(false); - const [commentError, setCommentError] = useState(undefined); - - const toggleEditComment = () => { - setEditComment(!editComment); - } - - const handleAlert = (event, reason) => { - if (reason === 'clickaway') { - return; - } - setAlert(false); - }; - - - const deleteComment = async () => { - try { - await window.point.contract.send({contract: 'PointSocial', method: 'deleteCommentForPost', params: [postId, comment.id]}); - await reloadComments(); - } catch (e) { - console.error('Error deleting post: ', e.message); - setCommentError('Error deleting post: ', e.message); - setAlert(true); - } - } - - const date = {`(${format(comment.createdAt)})`}; - const editor = ; - - return ( - (editComment)? editor : - - { walletAddress === comment.from ? - [ - You commented: , date, - Edit, - Delete - ]: - [{comment.identity} commented:, date] - } - - {comment.contents} - - - { commentError } - - - - ) -} - -export default Comment \ No newline at end of file diff --git a/src/components/comments/CommentEditor.jsx b/src/components/comments/CommentEditor.jsx deleted file mode 100644 index bda4afa..0000000 --- a/src/components/comments/CommentEditor.jsx +++ /dev/null @@ -1,85 +0,0 @@ -import './comments.css' -import { useState } from "react"; -import CommentManager from "../../services/CommentManager" - -const CommentEditor = ({ commentId, content, toggleEditComment, reloadComments }) => { - const DEFAULT_BTN_LABEL = 'Comment' - - const [btnLabel, setBtnLabel] = useState(DEFAULT_BTN_LABEL); - const [btnEnabled, setBtnEnabled] = useState(false); - - const [contents, setContents] = useState(content); - - const onContentsChange = event => { - let newContents = event.target.value; - setContents(newContents); - setBtnEnabled(newContents && newContents.trim().length > 0); - } - - const setSaving = (saving) => { - setBtnEnabled(!saving); - saving ? setBtnLabel('Saving...') : setBtnLabel(DEFAULT_BTN_LABEL); - } - - const cancelEditing = () => { - setSaving(false); - setBtnEnabled(false); - toggleEditComment(); - } - - const onFocus = event => { - const element = event.target; - element.selectionStart = element.value.length; - } - - const submitHandler = async (e) => { - e.preventDefault(); - setSaving(true); - - try { - // Save the post content to the storage layer and keep the storage id - let {data: storageId} = await window.point.storage.putString({data: contents}); - // Save the post contents storage id in the PoinSocial Smart Contract - await CommentManager.editComment(commentId, storageId); - setSaving(false); - // calling renderCommentsImmediate instead of fetching the comments due to issues with fetching content too soon from Arweave after posting. - // PD: using a timeout of 1000 apparently works - reloadComments(); - setContents(''); - toggleEditComment(false); - } catch (err) { - setSaving(false); - console.error('Error: ', err); - } - }; - - return ( - - - - - - - Cancel - - - {btnLabel} - - - - - - ) -} - -export default CommentEditor diff --git a/src/components/comments/Comments.jsx b/src/components/comments/Comments.jsx deleted file mode 100644 index 1a7cbc6..0000000 --- a/src/components/comments/Comments.jsx +++ /dev/null @@ -1,133 +0,0 @@ -import "./comments.css"; -import { useState, useEffect } from "react"; -import { useAppContext } from '../../context/AppContext'; -import Comment from './Comment' -import CircularProgress from '@material-ui/core/CircularProgress'; -import Box from '@material-ui/core/Box'; -import { makeStyles } from '@material-ui/core/styles'; -import CommentManager from "../../services/CommentManager" - -const useStyles = makeStyles((theme) => ({ - root: { - display: 'flex', - alignItems: 'center', - justifyContent: 'center' - } -})); - -const Comments = ({ postId, commentsCount, setCommentsCount, reloadPostCounters }) => { - const DEFAULT_BTN_LABEL = 'Comment' - const [comments, setComments] = useState([]) - const [contents, setContents] = useState() - const [btnLabel, setBtnLabel] = useState(DEFAULT_BTN_LABEL); - const [btnEnabled, setBtnEnabled] = useState(false); - const [loading, setLoading] = useState(true); - const { walletAddress } = useAppContext(); - const classes = useStyles(); - - const onContentsChange = event => { - let newContents = event.target.value; - setContents(newContents) - setBtnEnabled(newContents && newContents.trim().length > 0) - } - - const setSaving = (saving) => { - setBtnEnabled(!saving); - saving ? setBtnLabel('Saving...') : setBtnLabel(DEFAULT_BTN_LABEL); - } - - const getComments = async () => { - setLoading(true); - const comments = await fetchComments(); - setComments(comments); - setLoading(false); - } - - const reloadComments = async() => { - setLoading(true); - await new Promise((res, rej) => setTimeout(res, 1000)); - await reloadPostCounters(); - await getComments(); - setLoading(false); - } - - useEffect(() => { - getComments() - }, [postId]) - - const fetchComments = async () => { - const response = await window.point.contract.call({contract: 'PointSocial', method: 'getAllCommentsForPost', params: [postId]}); - - const comments = response.data.filter(r => (parseInt(r[3]) !== 0)).map(([id, from, contents, createdAt]) => ( - {id, from, contents, createdAt: createdAt*1000} - ) - ) - - const commentsContent = await Promise.all(comments.map(async (comment) => { - const {data: contents} = await window.point.storage.getString({ id: comment.contents, encoding: 'utf-8' }); - const {data: {identity}} = await window.point.identity.ownerToIdentity({owner: comment.from}); - comment.identity = identity; - comment.contents = contents; - return comment; - })) - - return commentsContent; - } - - const submitHandler = async (e) => { - e.preventDefault(); - setSaving(true); - - try { - // Save the post content to the storage layer and keep the storage id - let {data: storageId} = await window.point.storage.putString({data: contents}); - // Save the post contents storage id in the PoinSocial Smart Contract - await CommentManager.addComment(postId, storageId) - setSaving(false); - // calling renderCommentsImmediate instead of fetching the comments due to issues with fetching content too soon from Arweave after posting. - //renderCommentsImmediate(contents); - reloadComments(); - setContents(''); - // await getComments(); - } catch (err) { - setSaving(false); - console.error('Error: ', err); - } - }; - - const loadingBlock = ; - - return ( - - {loading? loadingBlock: - [ - - - - {btnLabel} - - , - , - (!loading && comments.length === 0) && 'No comments yet. Be the first!', - comments.filter(c => c.createdAt > 0).map((comment) => ([ - , ]) - )] - } - - ) -} - -export default Comments diff --git a/src/components/comments/comments.css b/src/components/comments/comments.css deleted file mode 100644 index 178d5f7..0000000 --- a/src/components/comments/comments.css +++ /dev/null @@ -1,79 +0,0 @@ - .commentCorners { - border-radius: 5px; - border: 1px solid #B4C1CE; - padding: 12px 8px; - width: calc(100% - 100px); - } - - .commentButton{ - border: none; - margin: 5px; - padding: 7px; - border-radius: 5px; - background-color: #1C385B; - font-weight: 500; - cursor: pointer; - color: white; - width:80px; - } - - .comment { - font-size: 14px; - color: white; - } - - .commentFrom { - font-weight: 500; - } - - .commentDate { - margin: 0 5px; - } - - .commentWrapper { - /* padding: 10px; */ - } - - .commentHr { - margin: 20px 0; - background:#dce2ea; - height: 1px; - border:none; - } - - .commentBottom { - display: flex; - align-items: center; - justify-content: space-between; - } - - p { - white-space: pre-wrap; - } - - .commentText { - margin: 5px; - margin-left: 10px; - font-size: 13px; - } - - .commentEditText { - margin-left: 5px; - cursor: pointer; - border-bottom: 1px dashed darkblue; - font-size: 10px; - } - - .commentDeleteText { - margin-left: 5px; - cursor: pointer; - border-bottom: 1px dashed darkred; - font-size: 10px; - } - - .commentButtons { - margin: 5px; - display: block; - align-items: center; - justify-content: space-between; - } diff --git a/src/components/feed/DiscoverFeed.jsx b/src/components/feed/DiscoverFeed.jsx new file mode 100644 index 0000000..8944a5e --- /dev/null +++ b/src/components/feed/DiscoverFeed.jsx @@ -0,0 +1,256 @@ +import "./feed.css"; +import { useState, useEffect } from "react"; +import { useAppContext } from '../../context/AppContext'; +import useInView from 'react-cool-inview' +import { makeStyles } from '@material-ui/core/styles'; + +import unionWith from "lodash/unionWith"; +import isEqual from "lodash/isEqual"; +import orderBy from "lodash/orderBy"; + +import { Box, Button, Snackbar, SnackbarContent, Typography } from '@material-ui/core'; + +import HourglassEmptyOutlinedIcon from '@material-ui/icons/HourglassEmptyOutlined'; +import CircularProgressWithIcon from '../generic/CircularProgressWithIcon'; +import InboxOutlinedIcon from '@material-ui/icons/InboxOutlined'; +import PostCard from "../post/PostCard"; + +import EventConstants from "../../events"; +import PostManager from '../../services/PostManager'; +import UserManager from "../../services/UserManager"; + +const NUM_POSTS_PER_CALL = 10; + +const useStyles = makeStyles((theme) => ({ + root: { + padding: 0, + margin: 0, + marginTop: '10px', + maxWidth: '900px' + }, + observer: { + display: 'flex', + justifyContent: 'center' + }, + empty: { + padding: theme.spacing(2, 2), + display: "flex", + flexDirection: "column", + alignItems:"center", + justifyContent: "center" + }, + backdrop: { + zIndex: theme.zIndex.drawer + 1, + }, + container: { + display: "flex", + height: "100%", + minHeight: "50vh", + flexDirection: "column", + }, + separator: { + marginTop: "20px", + marginBottom: "20px", + }, + extendedIcon: { + marginRight: theme.spacing(1), + }, +})); + +const DiscoverFeed = ({ setAlert, setUpperLoading }) => { + const {observe} = useInView({ + onEnter: async({observe,unobserve}) => { + if(length === posts.length) return; + unobserve(); + await getPosts(); + observe(); + } + }); + const styles = useStyles(); + const [posts, setPosts] = useState([]) + const [renderedPosts, setRenderedPosts] = useState([]) + const [length, setLength] = useState(0); + const [loading, setLoading] = useState(false); + const [reload, setReload] = useState(false); + + const { walletAddress, events } = useAppContext(); + + // sorts accending (newest first) + const compareByTimestamp = ( post1, post2 ) => { + if ( post1.createdAt < post2.createdAt ){ + return 1; + } + if ( post1.createdAt > post2.createdAt ){ + return -1; + } + return 0; + } + + useEffect(()=>{ + reloadPosts(); + }, []); + + useEffect(() => { + getEvents(); + return () => { + events.listeners["PointSocial"]["StateChange"].removeListener("StateChange", handleEvents, { type: 'discover-feed'}); + events.unsubscribe("PointSocial", "StateChange"); + }; + }, []); + + const getEvents = async() => { + try { + (await events.subscribe("PointSocial", "StateChange")).on("StateChange", handleEvents, { type: 'discover-feed'}); + } + catch(error) { + console.log(error.message); + } + } + + const handleEvents = async(event) => { + if (event) { + if (event.component === EventConstants.Component.Post) { + switch(event.action) { + case EventConstants.Action.Delete: + deletePost(event.id); + break; + default: + break; + } + } + } + } + + const getPostsLength = async() => { + try { + setLoading(true); + const data = await PostManager.getAllPostsLength(); + setLength(Number(data)); + } + catch(error) { + console.log(error.message); + setAlert(error.message); + } + setLoading(false); + } + + const fetchPosts = async (onlyNew = false) => { + try { + setLoading(true); + const lastId = Number(await PostManager.getLastPostId()); + const lastCurrentId = (posts.length > 0)? posts[posts.length - 1].id : lastId; + const data = (lastId > 0)? await PostManager.getPaginatedPosts(onlyNew?lastId:lastCurrentId,NUM_POSTS_PER_CALL,0) : []; + + const newPosts = data.filter(r => (parseInt(r[4]) !== 0)) + .map(([id, from, contents, image, createdAt, likesCount, commentsCount, dislikesCount, liked, disliked, flagged]) => ( + { + id, + from, + contents, + image, + createdAt: createdAt*1000, + likesCount: parseInt(likesCount, 10), + dislikesCount: parseInt(dislikesCount, 10), + commentsCount: parseInt(commentsCount, 10), + liked, + disliked, + flagged + } + ) + ); + + return await Promise.all(newPosts.map(async post => { + try { + post.weight = (await UserManager.isFollowing(walletAddress, post.from))? 1: 0; + } + catch(error) { + console.warn(error.message); + } + return post; + })); + //return newPosts; + + } catch(error) { + console.log(error.message); + setAlert(error.message); + } + finally { + setLoading(false); + } + } + + const getPosts = async (loadNew = false) => { + try { + setLoading(true); + const posts = await fetchPosts(loadNew); + setPosts(prev => { + const result = unionWith(prev, posts, isEqual); + //result.sort(compareByTimestamp); + console.log("POSTS:"); + console.log(result); + return result; + }); + } + catch(error) { + console.log(error); + setAlert(error.message); + } + finally { + setLoading(false); + } + } + + const reloadPosts = async () => { + await getPostsLength(); + await getPosts(true); + setReload(false); + } + + const deletePost = async (postId) => { + await getPostsLength(); + setPosts((posts) => posts.filter(post => post.id !== postId)); + } + + return ( + <> + + + { + (!loading && posts.length === 0)? + + + + {`No posts yet.`} + + + + : + orderBy(posts.filter(post => post.createdAt > 0), ['weight', 'likesCount', 'commentsCount', 'dislikesCount', 'createdAt'], ['desc', 'desc', 'desc', 'asc', 'desc']) + .map((post) => ( + + + + )) + } + + { + loading && + } props={{color : "inherit"}} /> + } + + + + > + ); + +} +export default DiscoverFeed diff --git a/src/components/feed/Feed.jsx b/src/components/feed/Feed.jsx index 6079fec..9d4c47a 100644 --- a/src/components/feed/Feed.jsx +++ b/src/components/feed/Feed.jsx @@ -158,7 +158,7 @@ const Feed = ({ account, setAlert, setUpperLoading, canPost=false }) => { PostManager.getPaginatedPosts(onlyNew?0:posts.length,NUM_POSTS_PER_CALL)); const newPosts = data.filter(r => (parseInt(r[4]) !== 0)) - .map(([id, from, contents, image, createdAt, likesCount, commentsCount, dislikesCount, liked, disliked]) => ( + .map(([id, from, contents, image, createdAt, likesCount, commentsCount, dislikesCount, liked, disliked, flagged]) => ( { id, from, @@ -170,19 +170,12 @@ const Feed = ({ account, setAlert, setUpperLoading, canPost=false }) => { commentsCount: parseInt(commentsCount, 10), liked, disliked, + flagged } ) ); - return await Promise.all(newPosts.map(async post => { - try { - post.isFlagged = await PostManager.isFlaggedPost(post.id); - } - catch(error) { - console.warn(error.message); - } - return post; - })); + return newPosts; } catch(error) { console.log(error.message); diff --git a/src/components/feed/FollowFeed.jsx b/src/components/feed/FollowFeed.jsx new file mode 100644 index 0000000..94d94b2 --- /dev/null +++ b/src/components/feed/FollowFeed.jsx @@ -0,0 +1,260 @@ +import "./feed.css"; +import { useState, useEffect } from "react"; +import { useAppContext } from '../../context/AppContext'; +import useInView from 'react-cool-inview' +import { makeStyles } from '@material-ui/core/styles'; + +import unionWith from "lodash/unionWith"; +import isEqual from "lodash/isEqual"; + +import { Box, Button, Snackbar, SnackbarContent, Typography } from '@material-ui/core'; + +import HourglassEmptyOutlinedIcon from '@material-ui/icons/HourglassEmptyOutlined'; +import CircularProgressWithIcon from '../generic/CircularProgressWithIcon'; +import InboxOutlinedIcon from '@material-ui/icons/InboxOutlined'; +import PostCard from "../post/PostCard"; + +import EventConstants from "../../events"; +import PostManager from '../../services/PostManager'; +import UserManager from "../../services/UserManager"; + +const NUM_POSTS_PER_CALL = 5; + +const useStyles = makeStyles((theme) => ({ + root: { + padding: 0, + margin: 0, + marginTop: '10px', + maxWidth: '900px' + }, + observer: { + display: 'flex', + justifyContent: 'center' + }, + empty: { + padding: theme.spacing(2, 2), + display: "flex", + flexDirection: "column", + alignItems:"center", + justifyContent: "center" + }, + backdrop: { + zIndex: theme.zIndex.drawer + 1, + }, + container: { + display: "flex", + height: "100%", + minHeight: "50vh", + flexDirection: "column", + }, + separator: { + marginTop: "20px", + marginBottom: "20px", + }, + extendedIcon: { + marginRight: theme.spacing(1), + }, +})); + +const FollowFeed = ({ setAlert, setUpperLoading}) => { + const {observe} = useInView({ + onEnter: async({observe,unobserve}) => { + if(length === posts.length) return; + unobserve(); + await getPosts(); + observe(); + } + }); + const styles = useStyles(); + const [posts, setPosts] = useState([]) + const [length, setLength] = useState(0); + const [loading, setLoading] = useState(false); + const [reload, setReload] = useState(false); + + const { walletAddress, events } = useAppContext(); + + // sorts accending (newest first) + const compareByTimestamp = ( post1, post2 ) => { + if ( post1.createdAt < post2.createdAt ){ + return 1; + } + if ( post1.createdAt > post2.createdAt ){ + return -1; + } + return 0; + } + + useEffect(()=>{ + reloadPosts(); + }, []); + + useEffect(() => { + getEvents(); + return () => { + events.listeners["PointSocial"]["StateChange"].removeListener("StateChange", handleEvents, { type: 'feed'}); + events.unsubscribe("PointSocial", "StateChange"); + }; + }, []); + + const getEvents = async() => { + try { + (await events.subscribe("PointSocial", "StateChange")).on("StateChange", handleEvents, { type: 'feed'}); + } + catch(error) { + console.log(error.message); + } + } + + const handleEvents = async(event) => { + if (event) { + if (event.component === EventConstants.Component.Feed) { + switch(event.action) { + case EventConstants.Action.Create: + if (await UserManager.isFollowing(walletAddress, event.from)) { + setReload(true); + } + break; + default: + break; + } + } + else if (event.component === EventConstants.Component.Post) { + switch(event.action) { + case EventConstants.Action.Delete: + deletePost(event.id); + break; + default: + break; + } + } + } + } + + const getPostsLength = async() => { + try { + setLoading(true); + const data = await PostManager.getAllPostsLength(); + setLength(Number(data)); + } + catch(error) { + console.log(error.message); + setAlert(error.message); + } + setLoading(false); + } + + const fetchPosts = async (onlyNew = false) => { + try { + setLoading(true); + const lastId = Number(await PostManager.getLastPostId()); + const lastCurrentId = (posts.length > 0)? parseInt(posts[posts.length - 1].id) : lastId; + const data = (lastId > 0)? await PostManager.getPaginatedPosts(onlyNew?lastId:lastCurrentId,NUM_POSTS_PER_CALL,1) : []; + + const newPosts = data.filter(r => (parseInt(r[4]) !== 0)) + .map(([id, from, contents, image, createdAt, likesCount, commentsCount, dislikesCount, liked, disliked,flagged]) => ( + { + id, + from, + contents, + image, + createdAt: createdAt*1000, + likesCount: parseInt(likesCount, 10), + dislikesCount: parseInt(dislikesCount, 10), + commentsCount: parseInt(commentsCount, 10), + liked, + disliked, + flagged + } + ) + ); + + return newPosts; + + } catch(error) { + console.log(error.message); + setAlert(error.message); + } + finally { + setLoading(false); + } + } + + const getPosts = async (loadNew = false) => { + try { + setLoading(true); + const posts = await fetchPosts(loadNew); + setPosts(prev => { + const result = unionWith(prev, posts, isEqual); + result.sort(compareByTimestamp); + return result; + }); + } + catch(error) { + console.log(error); + setAlert(error.message); + } + finally { + setLoading(false); + } + } + + const reloadPosts = async () => { + await getPostsLength(); + await getPosts(true); + setReload(false); + } + + const deletePost = async (postId) => { + await getPostsLength(); + setPosts((posts) => posts.filter(post => post.id !== postId)); + } + + return ( + <> + + {setReload(false)}}>Dismiss{reloadPosts()}}>Reload>} + /> + + + + { + (!loading && posts.length === 0)? + + + + {'No posts yet! Start following somebody!'} + + + + : + posts.filter(post => post.createdAt > 0).map((post) => ( + + + + )) + } + + { + loading && + } props={{color : "inherit"}} /> + } + + + + > + ); + +} +export default FollowFeed diff --git a/src/components/feed/FreshFeed.jsx b/src/components/feed/FreshFeed.jsx new file mode 100644 index 0000000..9a9f341 --- /dev/null +++ b/src/components/feed/FreshFeed.jsx @@ -0,0 +1,264 @@ +import "./feed.css"; +import { useState, useEffect } from "react"; +import { useAppContext } from '../../context/AppContext'; +import useInView from 'react-cool-inview' +import { makeStyles } from '@material-ui/core/styles'; + +import unionWith from "lodash/unionWith"; +import isEqual from "lodash/isEqual"; + +import { Box, Button, Snackbar, SnackbarContent, Typography } from '@material-ui/core'; + +import HourglassEmptyOutlinedIcon from '@material-ui/icons/HourglassEmptyOutlined'; +import CircularProgressWithIcon from '../generic/CircularProgressWithIcon'; +import InboxOutlinedIcon from '@material-ui/icons/InboxOutlined'; +import PostCard from "../post/PostCard"; + +import EventConstants from "../../events"; +import PostManager from '../../services/PostManager'; + +const NUM_POSTS_PER_CALL = 5; + +const useStyles = makeStyles((theme) => ({ + root: { + padding: 0, + margin: 0, + marginTop: '10px', + maxWidth: '900px' + }, + observer: { + display: 'flex', + justifyContent: 'center' + }, + empty: { + padding: theme.spacing(2, 2), + display: "flex", + flexDirection: "column", + alignItems:"center", + justifyContent: "center" + }, + backdrop: { + zIndex: theme.zIndex.drawer + 1, + }, + container: { + display: "flex", + height: "100%", + minHeight: "50vh", + flexDirection: "column", + }, + separator: { + marginTop: "20px", + marginBottom: "20px", + }, + extendedIcon: { + marginRight: theme.spacing(1), + }, +})); + +const FreshFeed = ({ setAlert, setUpperLoading, canPost=false }) => { + const {observe} = useInView({ + onEnter: async({observe,unobserve}) => { + if(length === posts.length) return; + unobserve(); + await getPosts(); + observe(); + } + }); + const styles = useStyles(); + const [posts, setPosts] = useState([]) + const [length, setLength] = useState(0); + const [loading, setLoading] = useState(false); + const [reload, setReload] = useState(false); + + const { walletAddress, events } = useAppContext(); + + // sorts accending (newest first) + const compareByTimestamp = ( post1, post2 ) => { + if ( post1.createdAt < post2.createdAt ){ + return 1; + } + if ( post1.createdAt > post2.createdAt ){ + return -1; + } + return 0; + } + + useEffect(()=>{ + reloadPosts(); + }, []); + + useEffect(() => { + getEvents(); + return () => { + events.listeners["PointSocial"]["StateChange"].removeListener("StateChange", handleEvents, { type: 'feed'}); + events.unsubscribe("PointSocial", "StateChange"); + }; + }, []); + + const getEvents = async() => { + try { + (await events.subscribe("PointSocial", "StateChange")).on("StateChange", handleEvents, { type: 'feed'}); + } + catch(error) { + console.log(error.message); + } + } + + const handleEvents = async(event) => { + if (event) { + if (event.component === EventConstants.Component.Feed) { + switch(event.action) { + case EventConstants.Action.Create: + if (event.from.toString().toLowerCase() === walletAddress.toLowerCase()) { + // Autoload own posts + await reloadPosts(); + } + else { + setReload(true); + } + break; + default: + break; + } + } + else if (event.component === EventConstants.Component.Post) { + switch(event.action) { + case EventConstants.Action.Delete: + deletePost(event.id); + break; + default: + break; + } + } + } + } + + const getPostsLength = async() => { + try { + setLoading(true); + const data = await PostManager.getAllPostsLength(); + setLength(Number(data)); + } + catch(error) { + console.log(error.message); + setAlert(error.message); + } + setLoading(false); + } + + const fetchPosts = async (onlyNew = false) => { + try { + setLoading(true); + const lastId = Number(await PostManager.getLastPostId()); + const lastCurrentId = (posts.length > 0)? parseInt(posts[posts.length - 1].id) : lastId; + const data = (lastId > 0)? await PostManager.getPaginatedPosts(onlyNew?lastId:lastCurrentId,NUM_POSTS_PER_CALL,2) : []; + console.log(posts); + + const newPosts = data.filter(r => (parseInt(r[4]) !== 0)) + .map(([id, from, contents, image, createdAt, likesCount, commentsCount, dislikesCount, liked, disliked, flagged]) => ( + { + id, + from, + contents, + image, + createdAt: createdAt*1000, + likesCount: parseInt(likesCount, 10), + dislikesCount: parseInt(dislikesCount, 10), + commentsCount: parseInt(commentsCount, 10), + liked, + disliked, + flagged + } + ) + ); + + return newPosts; + + } catch(error) { + console.log(error.message); + setAlert(error.message); + } + finally { + setLoading(false); + } + } + + const getPosts = async (loadNew = false) => { + try { + setLoading(true); + const posts = await fetchPosts(loadNew); + setPosts(prev => { + const result = unionWith(prev, posts, isEqual); + result.sort(compareByTimestamp); + return result; + }); + } + catch(error) { + console.log(error); + setAlert(error.message); + } + finally { + setLoading(false); + } + } + + const reloadPosts = async () => { + await getPostsLength(); + await getPosts(true); + setReload(false); + } + + const deletePost = async (postId) => { + await getPostsLength(); + setPosts((posts) => posts.filter(post => post.id !== postId)); + } + + return ( + <> + + {setReload(false)}}>Dismiss{reloadPosts()}}>Reload>} + /> + + + + { + (!loading && posts.length === 0)? + + + + {`No posts yet.${ canPost? " Be the first!" : "" }`} + + + + : + posts.filter(post => post.createdAt > 0).map((post) => ( + + + + )) + } + + { + loading && + } props={{color : "inherit"}} /> + } + + + + > + ); + +} +export default FreshFeed diff --git a/src/components/feed/TopFeed.jsx b/src/components/feed/TopFeed.jsx new file mode 100644 index 0000000..115706f --- /dev/null +++ b/src/components/feed/TopFeed.jsx @@ -0,0 +1,250 @@ +import "./feed.css"; +import { useState, useEffect } from "react"; +import { useAppContext } from '../../context/AppContext'; +import useInView from 'react-cool-inview' +import { makeStyles } from '@material-ui/core/styles'; + +import unionWith from "lodash/unionWith"; +import isEqual from "lodash/isEqual"; +import orderBy from "lodash/orderBy"; + +import { Box, Button, Snackbar, SnackbarContent, Typography } from '@material-ui/core'; + +import HourglassEmptyOutlinedIcon from '@material-ui/icons/HourglassEmptyOutlined'; +import CircularProgressWithIcon from '../generic/CircularProgressWithIcon'; +import InboxOutlinedIcon from '@material-ui/icons/InboxOutlined'; +import PostCard from "../post/PostCard"; + +import EventConstants from "../../events"; +import PostManager from '../../services/PostManager'; + +const NUM_POSTS_PER_CALL = 20; + +const useStyles = makeStyles((theme) => ({ + root: { + padding: 0, + margin: 0, + marginTop: '10px', + maxWidth: '900px' + }, + observer: { + display: 'flex', + justifyContent: 'center' + }, + empty: { + padding: theme.spacing(2, 2), + display: "flex", + flexDirection: "column", + alignItems:"center", + justifyContent: "center" + }, + backdrop: { + zIndex: theme.zIndex.drawer + 1, + }, + container: { + display: "flex", + height: "100%", + minHeight: "50vh", + flexDirection: "column", + }, + separator: { + marginTop: "20px", + marginBottom: "20px", + }, + extendedIcon: { + marginRight: theme.spacing(1), + }, +})); + +const TopFeed = ({ setAlert, setUpperLoading, canPost=false }) => { + const {observe} = useInView({ + onEnter: async({observe,unobserve}) => { + if(length === posts.length) return; + unobserve(); + await getPosts(); + observe(); + } + }); + const styles = useStyles(); + const [posts, setPosts] = useState([]) + const [length, setLength] = useState(0); + const [loading, setLoading] = useState(false); + const [reload, setReload] = useState(false); + + const { walletAddress, events } = useAppContext(); + + // sorts accending (newest first) + const compareByTimestamp = ( post1, post2 ) => { + if ( post1.createdAt < post2.createdAt ){ + return 1; + } + if ( post1.createdAt > post2.createdAt ){ + return -1; + } + return 0; + } + + useEffect(()=>{ + reloadPosts(); + }, []); + + useEffect(() => { + getEvents(); + return () => { + events.listeners["PointSocial"]["StateChange"].removeListener("StateChange", handleEvents, { type: 'feed'}); + events.unsubscribe("PointSocial", "StateChange"); + }; + }, []); + + const getEvents = async() => { + try { + (await events.subscribe("PointSocial", "StateChange")).on("StateChange", handleEvents, { type: 'feed'}); + } + catch(error) { + console.log(error.message); + } + } + + const handleEvents = async(event) => { + if (event) { + if (event.component === EventConstants.Component.Post) { + switch(event.action) { + case EventConstants.Action.Delete: + deletePost(event.id); + break; + default: + break; + } + } + } + } + + const getPostsLength = async() => { + try { + setLoading(true); + const data = await PostManager.getAllPostsLength(); + setLength(Number(data)); + } + catch(error) { + console.log(error.message); + setAlert(error.message); + } + setLoading(false); + } + + const fetchPosts = async (onlyNew = false) => { + try { + setLoading(true); + const lastId = Number(await PostManager.getLastPostId()); + const lastCurrentId = (posts.length > 0)? parseInt(posts[posts.length - 1].id) : lastId; + const data = (lastId > 0)? await PostManager.getPaginatedPosts(onlyNew?lastId:lastCurrentId,NUM_POSTS_PER_CALL,3) : []; + + const newPosts = data.filter(r => (parseInt(r[4]) !== 0)) + .map(([id, from, contents, image, createdAt, likesCount, commentsCount, dislikesCount, liked, disliked, flagged]) => ( + { + id, + from, + contents, + image, + createdAt: createdAt*1000, + likesCount: parseInt(likesCount, 10), + dislikesCount: parseInt(dislikesCount, 10), + commentsCount: parseInt(commentsCount, 10), + liked, + disliked, + flagged + } + ) + ); + + return newPosts; + + } catch(error) { + console.log(error.message); + setAlert(error.message); + } + finally { + setLoading(false); + } + } + + const getPosts = async (loadNew = false) => { + try { + setLoading(true); + const posts = await fetchPosts(loadNew); + setPosts(prev => { + const result = unionWith(prev, posts, isEqual); + result.sort(compareByTimestamp); + return result; + }); + } + catch(error) { + console.log(error); + setAlert(error.message); + } + finally { + setLoading(false); + } + } + + const reloadPosts = async () => { + await getPostsLength(); + await getPosts(true); + setReload(false); + } + + const deletePost = async (postId) => { + await getPostsLength(); + setPosts((posts) => posts.filter(post => post.id !== postId)); + } + + return ( + <> + + {setReload(false)}}>Dismiss{reloadPosts()}}>Reload>} + /> + + + + { + (!loading && posts.length === 0)? + + + + {`No posts yet.${ canPost? " Be the first!" : "" }`} + + + + : + orderBy(posts.filter(post => post.createdAt > 0), ['likesCount', 'commentsCount', 'dislikesCount'], ['desc', 'desc', 'asc']) + .map((post) => ( + + + + )) + } + + { + loading && + } props={{color : "inherit"}} /> + } + + + + > + ); + +} +export default TopFeed diff --git a/src/components/feed/feed.css b/src/components/feed/feed.css index a1f16bf..ce572b6 100644 --- a/src/components/feed/feed.css +++ b/src/components/feed/feed.css @@ -14,11 +14,10 @@ font-weight: 400; } .no-post-to-show{ - background:url(http://neckcode.com/feed-show-ico.svg) no-repeat white; display: block; -text-align: center; -padding: 30px; -margin: 10px 0; -border-radius: 6px; -font-size:13px; + text-align: center; + padding: 30px; + margin: 10px 0; + border-radius: 6px; + font-size:13px; } diff --git a/src/components/generic/RichTextField.jsx b/src/components/generic/RichTextField.jsx index 2da268e..6780efe 100644 --- a/src/components/generic/RichTextField.jsx +++ b/src/components/generic/RichTextField.jsx @@ -75,7 +75,19 @@ const RichTextField = forwardRef(({value, minLength, maxLength, placeholder, dis autoFocus disabled={processing} /> - + diff --git a/src/components/post/Post.jsx b/src/components/post/Post.jsx deleted file mode 100644 index eb9c692..0000000 --- a/src/components/post/Post.jsx +++ /dev/null @@ -1,197 +0,0 @@ -import "./post.css"; -import { useState, useEffect } from "react"; -import { useAppContext } from '../../context/AppContext'; -import { format } from "timeago.js"; -import { Link } from "wouter"; -import likeImg from '../../assets/like.png'; -import profileImg from '../../assets/profile-pic.jpg'; -import Comments from '../comments/Comments' -import PostEditor from "./PostEditor"; -import CircularProgress from '@material-ui/core/CircularProgress'; -import { makeStyles } from '@material-ui/core/styles'; - -import Snackbar from '@material-ui/core/Snackbar'; -import MuiAlert from '@material-ui/lab/Alert'; - -function Alert(props) { - return ; -} - -const useStyles = makeStyles((theme) => ({ - root: { - display: 'flex', - alignItems: 'center', - justifyContent: 'center' - } -})); - -export default function Post({ post, reloadPostCounts, reloadPostContent, renderDeletedPostImmediate }) { - const EMPTY_MEDIA = '0x0000000000000000000000000000000000000000000000000000000000000000'; - const [showComments, setShowComments] = useState(false); - const [editPost, setEditPost] = useState(false); - const [commentsCount, setCommentsCount] = useState(post.commentsCount); - const { walletAddress } = useAppContext(); - const [loadImgError, setLoadImgError] = useState(false); - const [loadVideoError, setLoadVideoError] = useState(false); - const [loading, setLoading] = useState(false); - const [alert, setAlert] = useState(false); - const [postError, setPostError] = useState(undefined); - - const classes = useStyles(); - - const toggleShowComments = () => { - setShowComments(!showComments); - } - - const toggleEditPost = () => { - setEditPost(!editPost); - } - - const handleAlert = (event, reason) => { - if (reason === 'clickaway') { - return; - } - setAlert(false); - }; - - const deletePost = async () => { - try { - setLoading(true); - await window.point.contract.send({contract: 'PointSocial', method: 'deletePost', params: [post.id]}); - await renderDeletedPostImmediate(post.id); - } - catch (e) { - console.error('Error deleting post: ', e.message); - setLoading(false); - setPostError(`Error deleting post: ${e.message}`); - setAlert(true); - } - } - - const addLikeToPost = async () => { - try { - setLoading(true); - await window.point.contract.send({contract: 'PointSocial', method: 'addLikeToPost', params: [post.id]}); - reloadPostCounts(post.id); - } catch (e) { - console.error('Error updating likes: ', e.message); - setPostError(`Error updating likes: ${e.message}`); - setAlert(true); - } - finally { - setLoading(false); - } - }; - - const reloadPost = async (contents, image) => { - toggleEditPost(); - try { - setLoading(true); - reloadPostContent(post.id, contents, image); - } - catch(e) { - console.error('Error updating the post: ', e.message); - setPostError(`Error updating the post: ${e.message}`); - setAlert(true); - } - finally { - setLoading(false); - } - } - - const reloadPostCounters = async () => { - try { - setLoading(true); - const [likes, comments] = await reloadPostCounts(post.id); - setCommentsCount(comments); - } - catch(e) { - console.error('Error updating the post: ', e.message); - setPostError(`Error updating the post: ${e.message}`); - setAlert(true); - } - finally { - setLoading(false); - } - } - - const onImgErrorHandler = (e) => { - setLoadImgError(true); - } - - const onVideoErrorHandler = (e) => { - setLoadVideoError(true); - } - - let mediaTag; - if (!loadImgError){ - mediaTag = ; - }else{ - if(!loadVideoError){ - mediaTag = ; - }else{ - mediaTag = ''; - } - } - - const postedContent = {post?.contents} - const postedMedia = post.image !== EMPTY_MEDIA && mediaTag - const postEdit = (walletAddress === post.from) && Edit - const postDelete = (walletAddress === post.from) && Delete - const postLoading = - - return ( - - { loading? postLoading : - - - - - - - {walletAddress === post.from ? You posted : {post.identity}} - - - {format(post.createdAt)} - - - - { - editPost? - : - [postedContent, postedMedia] - } - - - - - {post.likesCount} people like it - - - {commentsCount} comments - { (parseInt(commentsCount) === 0) && postEdit } - { (parseInt(commentsCount) === 0) && postDelete } - - - - {showComments && } - - - } - - - { postError } - - - - ); -} diff --git a/src/components/post/PostCard.jsx b/src/components/post/PostCard.jsx index 5585776..581b1c2 100644 --- a/src/components/post/PostCard.jsx +++ b/src/components/post/PostCard.jsx @@ -23,6 +23,7 @@ import SaveOutlinedIcon from '@material-ui/icons/SaveOutlined'; import DeleteOutlineOutlinedIcon from '@material-ui/icons/DeleteOutlineOutlined'; import FlagOutlinedIcon from '@material-ui/icons/FlagOutlined'; import VisibilityOutlinedIcon from '@material-ui/icons/VisibilityOutlined'; +import PanoramaOutlinedIcon from '@material-ui/icons/PanoramaOutlined'; import AccountTreeOutlinedIcon from '@material-ui/icons/AccountTreeOutlined'; import LanguageOutlinedIcon from '@material-ui/icons/LanguageOutlined'; @@ -841,11 +842,11 @@ const PostCard = ({ aria-describedby="alert-dialog-description" > {`${ - post.isFlagged ? 'Unflag' : 'Flag' + post.flagged ? 'Unflag' : 'Flag' } post?`} - {`Are you sure you want to ${post.isFlagged ? 'unflag' : 'flag'} this post?`} + {`Are you sure you want to ${post.flagged ? 'unflag' : 'flag'} this post?`} @@ -853,7 +854,7 @@ const PostCard = ({ Cancel - {post.isFlagged ? 'Unflag' : 'Flag'} + {post.flagged ? 'Unflag' : 'Flag'} @@ -886,7 +887,7 @@ const PostCard = ({ - {post.isFlagged ? 'Unflag' : 'Flag'} + {post.flagged ? 'Unflag' : 'Flag'} )} @@ -968,12 +969,12 @@ const PostCard = ({ return ( <> - + {loading && } {flagged && ( { diff --git a/src/components/post/PostEditor.jsx b/src/components/post/PostEditor.jsx deleted file mode 100644 index 7ba4834..0000000 --- a/src/components/post/PostEditor.jsx +++ /dev/null @@ -1,152 +0,0 @@ -import "./postEditor.css"; -import { AttachFileTwoTone } from "@material-ui/icons"; -import { useRef, useState } from "react"; -import PostManager from "../../services/PostManager" - -export default function PostEditor({ post, toggleEditPost, reloadPost }) { - const DEFAULT_BTN_LABEL = 'Save' - const EMPTY_MEDIA = '0x0000000000000000000000000000000000000000000000000000000000000000'; - const EMPTY_CONTENT = '0x0000000000000000000000000000000000000000000000000000000000000000'; - const [contents, setContents] = useState(post.contents); - const [media, setMedia] = useState(post.image); - - const [selectedFile, setSelectedFile] = useState(); - const [preview, setPreview] = useState(`/_storage/${media}`) - - const [btnLabel, setBtnLabel] = useState(DEFAULT_BTN_LABEL); - const [btnEnabled, setBtnEnabled] = useState(false); - - const [loadImgError, setLoadImgError] = useState(false); - const [loadVideoError, setLoadVideoError] = useState(false); - - - const fileInputRef = useRef() - - const onContentsChange = event => { - let newContents = event.target.value; - setContents(newContents); - setBtnEnabled(newContents && newContents.trim().length > 0); - } - - const onFileChange = event => { - let fileToUpload = event.target.files[0]; - if(fileToUpload.type.startsWith('image') || fileToUpload.type.startsWith('video') ) { - if (fileToUpload.size > 100 * 1024 * 1024){ - alert('Point Social only supports image and video until 100 MB. Please change to a samller image or video file!') - } - setSelectedFile(event.target.files[0]); - setPreview(URL.createObjectURL(event.target.files[0])); - setBtnEnabled(true); - } else { - alert('Point Social only supports image and video uploads for now. Please change to an image or video file!') - } - }; - - const onFocus = event => { - const element = event.target; - element.selectionStart = element.value.length; - } - - const onImgErrorHandler = (e) => { - setLoadImgError(true); - } - - const onVideoErrorHandler = (e) => { - setLoadVideoError(true); - } - - let mediaTag; - if (!loadImgError) { - mediaTag = ; - } else { - if(!loadVideoError) { - mediaTag = ; - } else { - mediaTag = ''; - } - } - - const postedMedia = (media !== EMPTY_MEDIA) && mediaTag - - const setSaving = (saving) => { - setBtnEnabled(!saving); - saving ? setBtnLabel('Saving...') : setBtnLabel(DEFAULT_BTN_LABEL); - } - - const cancelEditing = () => { - setSaving(false); - setBtnEnabled(false); - toggleEditPost(); - } - - const submitHandler = async (e) => { - e.preventDefault(); - setSaving(true); - - try { - // Save the post content to the storage layer and keep the storage id - let {data: storageId} = (contents && contents.trim().length > 0)? await window.point.storage.putString({data: contents}) : { data: EMPTY_CONTENT }; - let imageId = media; - if(selectedFile){ - const formData = new FormData() - formData.append("postfile", selectedFile); - const res = await window.point.storage.postFile(formData); - imageId = res.data; - } - // Save the post contents storage id in the PoinSocial Smart Contract - await PostManager.editPost(post.id, storageId, imageId); - setSaving(false); - setContents(''); - setSelectedFile(); - setBtnEnabled(false); - try { fileInputRef.current.value = null } catch (error) {} - reloadPost(contents, imageId); - } catch (e) { - console.error('Error sharing post: ', e.message); - setSaving(false); - setContents(''); - setSelectedFile(); - setBtnEnabled(false); - try { fileInputRef.current.value = null } catch (error) {} - } - }; - - return ( - - - - { postedMedia } - - - - - - - - {btnLabel} - - - Cancel - - - - - ); -} diff --git a/src/components/post/post.css b/src/components/post/post.css deleted file mode 100644 index 3a58d3b..0000000 --- a/src/components/post/post.css +++ /dev/null @@ -1,119 +0,0 @@ - .post { - width: 100%; - border-radius: 6px; - -webkit-box-shadow: 0px 0px 16px -8px rgba(172, 173, 181, 0.68); - box-shadow: 0px 0px 16px -8px rgba(172, 173, 181, 0.68); - margin: 12px 0; - } - - .postWrapper { - padding: 15px; - } - - .postImage { - padding: 0; - display: block; - margin: 0 auto; - max-height: 100%; - max-width: 100%; - } - - .postText { - display: flex; - margin-top: 10px; - margin-bottom: 10px; - } - - .postTop { - display: flex; - align-items: center; - justify-content: space-between; - } - - .postTopLeft { - display: flex; - align-items: center; - } - - .postProfileImg { - width: 32px; - height: 32px; - border-radius: 50%; - object-fit: cover; - } - - .postUsername { - font-size: 15px; - font-weight: 500; - margin: 0 10px; - } - - .postDate{ - font-size: 12px; - } - - .postCenter{ - margin: 20px 0; - } - - .postImg{ - margin-top: 20px; - width: 100%; - max-height: 500px; - object-fit: contain; - } - - .postBottom{ - display: flex; - align-items: center; - justify-content: space-between; - } - - .postBottomLeft{ - display: flex; - align-items: center; - } - - .likeIcon{ - width: 24px; - height: 24px; - margin-right: 5px; - cursor: pointer; - } - - .postLikeCounter{ - font-size: 15px; - } - - .postCommentText{ - cursor: pointer; - border-bottom: 1px dashed gray; - font-size: 15px; - } - - .postEditText{ - margin-left: 5px; - cursor: pointer; - border-bottom: 1px dashed darkblue; - font-size: 10px; - } - - .postDeleteText{ - margin-left: 5px; - cursor: pointer; - border-bottom: 1px dashed darkred; - font-size: 10px; - } - - .comments { - margin-top: 10px; - } - .postDate{ - color:rgb(148, 159, 173); - } - .posted-id{ - color:#1c385b; - } - p { - white-space: pre-wrap; - } \ No newline at end of file diff --git a/src/components/post/postEditor.css b/src/components/post/postEditor.css deleted file mode 100644 index 158bde9..0000000 --- a/src/components/post/postEditor.css +++ /dev/null @@ -1,65 +0,0 @@ -.postEditor { - width: 100%; - border-radius: 6px; - -webkit-box-shadow: 0px 0px 16px -8px rgba(172, 173, 181, 0.68); - box-shadow: 0px 0px 16px -8px rgba(172, 173, 181, 0.68); -} - -.editHr { - margin: 20px 0; - background:#dce2ea; - height: 1px; - border:none; -} - -.editInput { - border: none; - width: 100%; -} - -.editInput:focus { - outline: none; -} - -.editBottom { - margin-top: 5px; - display: flex; - align-items: flex-start; - justify-content: space-between; - width: 100%; -} - -.editOptions{ - display: flex; - /* margin-left: 20px; */ -} - -.editFilePicker { - display: flex; - align-items: center; - margin-right: 15px; - cursor: pointer; -} - -.editIcon { - font-size: 18px; - margin-right: 3px; -} - -.editOptionText{ - font-size: 14px; - font-weight: 500; -} - -.editButton { - border: none; - border-radius: 5px; - margin-left: 5px; - background-color: #1C385B; - font-weight: 500; - cursor: pointer; - color: white; - width:80px; -} - - diff --git a/src/components/profile/ProfileCard.jsx b/src/components/profile/ProfileCard.jsx index f3d5892..20e4fc0 100644 --- a/src/components/profile/ProfileCard.jsx +++ b/src/components/profile/ProfileCard.jsx @@ -6,7 +6,6 @@ import { useTheme } from '@material-ui/core/styles'; import { makeStyles } from '@material-ui/core/styles'; import useMediaQuery from '@material-ui/core/useMediaQuery'; -import Avatar from '@material-ui/core/Avatar'; import Backdrop from '@material-ui/core/Backdrop'; import Box from '@material-ui/core/Box'; import Card from '@material-ui/core/Card'; @@ -36,15 +35,24 @@ import MoreVertIcon from '@material-ui/icons/MoreVert'; import Close from '@material-ui/icons/Close'; import RoomOutlinedIcon from '@material-ui/icons/RoomOutlined'; import PanoramaOutlinedIcon from '@material-ui/icons/PanoramaOutlined'; +import PersonAddIcon from '@material-ui/icons/PersonAdd'; +import BlockOutlinedIcon from '@material-ui/icons/BlockOutlined'; +import PersonAddDisabledIcon from '@material-ui/icons/PersonAddDisabled'; +import CheckOutlinedIcon from '@material-ui/icons/CheckOutlined'; +import LockOpenOutlinedIcon from '@material-ui/icons/LockOpenOutlined'; +import LockOutlinedIcon from '@material-ui/icons/LockOutlined'; import TabPanel from '../tabs/TabPanel'; import Feed from '../feed/Feed'; import UserAvatar from '../avatar/UserAvatar'; +import UserList from '../user/UserList'; import point from "../../services/PointSDK"; import UserManager from "../../services/UserManager"; import { Link } from "wouter"; +import EventConstants from "../../events"; + const MAX_FILE_SIZE = 100 * 1024 * 1024; const EMPTY = '0x0000000000000000000000000000000000000000000000000000000000000000'; @@ -201,6 +209,13 @@ const useStyles = makeStyles((theme) => ({ justify: "center", alignItems:"center" }, + followBox: { + display: 'flex', + justifyContent: "end", + justify: "end", + alignItems:"end", + margin: theme.spacing(2) + } })); const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { @@ -213,12 +228,22 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { const [name, setName] = useState(EMPTY); const [location, setLocation] = useState(EMPTY); const [about, setAbout] = useState(EMPTY); + const [followers, setFollowers] = useState(0); const [following, setFollowing] = useState(0); + const [followersList, setFollowersList] = useState([]); + const [followingList, setFollowingList] = useState([]); + const [avatar, setAvatar] = useState(EMPTY); const [banner, setBanner] = useState(EMPTY); const [profile, setProfile] = useState(); + const [isOwner, setIsOwner] = useState(false); + const [isFollowed, setFollowed] = useState(false); + const [isFollower, setFollower] = useState(false); + const [isBlocked, setIsBlocked] = useState(false); + const [imBlocked, setImBlocked] = useState(false); + const [loading, setLoading] = useState(true); const [actionsOpen, setActionsOpen] = useState(false); const [edit, setEdit] = useState(false); @@ -231,7 +256,7 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { const displayAboutRef = useRef(); const actionsAnchor = useRef(); - const { walletAddress, processing, setProcessing, setUserProfile } = useAppContext(); + const { walletAddress, setUserProfile, events } = useAppContext(); useEffect(() => { loadProfile(); @@ -241,6 +266,41 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { renderProfile(profile); }, [profile]); + useEffect(() => { + getEvents(); + return () => { + events.listeners["PointSocial"]["FollowEvent"].removeListener("FollowEvent", handleEvents, { type: 'profile', id: address}); + events.unsubscribe("PointSocial", "FollowEvent"); + }; + }, []); + + const getEvents = async() => { + try { + (await events.subscribe("PointSocial", "FollowEvent")).on("FollowEvent", handleEvents, { type: 'profile', id: address}); + } + catch(error) { + console.log(error.message); + } + } + + const handleEvents = async(event) => { + if (event && (((event.from.toLowerCase() === walletAddress.toLowerCase()) && + (event.to.toLowerCase() === address.toLowerCase())) || + ((event.to.toLowerCase() === walletAddress.toLowerCase()) && + (event.from.toLowerCase() === address.toLowerCase())))) { + switch(event.action) { + case EventConstants.FollowAction.Follow: + case EventConstants.FollowAction.UnFollow: + case EventConstants.FollowAction.Block: + case EventConstants.FollowAction.UnBlock: + await loadFollowStatus(); + break; + default: + break; + } + } + } + const renderProfile = async (profile) => { if (profile) { try { @@ -250,11 +310,10 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { const location = (profile.displayLocation === EMPTY)? "Point Network" : await point.getString(profile.displayLocation, { encoding: 'utf-8' }); setLocation(location); const about = (profile.displayLocation === EMPTY)? "Hey I'm using Point Social!" : await point.getString(profile.displayAbout, { encoding: 'utf-8' }); - setAbout(about); - setFollowers(profile.followersCount || 0); - setFollowing(profile.followingCount || 0); + setAbout(about); setAvatar(`/_storage/${profile.avatar}`); setBanner((profile.banner=== EMPTY)?defaultBanner:`/_storage/${profile.banner}`); + await loadFollowStatus(); setLoading(false); } catch(error) { @@ -263,6 +322,36 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { } } + const loadFollowStatus = async () => { + setFollowers(await UserManager.followersCount(address) || 0); + setFollowing(await UserManager.followingCount(address) || 0); + + try { + setFollowersList(await UserManager.followersList(address)); + } + catch(error) { + setFollowersList([]); + } + + try { + setFollowingList(await UserManager.followingList(address)); + } + catch(error) { + setFollowingList([]); + } + + const owner = address.toLowerCase() === walletAddress.toLowerCase(); + if (owner) { + setIsOwner(true); + } + else { + setFollowed(await UserManager.isFollowing(walletAddress, address)); + setFollower(await UserManager.isFollowing(address, walletAddress)); + setIsBlocked(await UserManager.isBlocked(walletAddress, address)); + setImBlocked(await UserManager.isBlocked(address, walletAddress)); + } + } + const loadProfile = async () => { try { const profile = await UserManager.getProfile(address); @@ -276,7 +365,7 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { followersCount: 0, followingCount: 0, }); - } + } } catch(error) { setAlert(error.message); @@ -304,6 +393,10 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { case 'cancel': cancelEdit(); break; + case 'block': + case 'unblock': + toggleBlock(); + break; } setActionsOpen(false); @@ -352,7 +445,6 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { }; const saveEdit = async () => { - setProcessing(true); setLoading(true); const newProfile = { ...profile }; @@ -407,7 +499,7 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { followingCount: 0, }; - const result = await UserManager.setProfile( + await UserManager.setProfile( updatedProfile.displayName, updatedProfile.displayLocation, updatedProfile.displayAbout, @@ -432,10 +524,53 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { } finally { setLoading(false); - setProcessing(false); } }; + const toggleFollow = async () => { + try { + setLoading(true); + if (isFollowed) { + await UserManager.unfollowUser(address); + setFollowed(false); + setAlert(`You're no longer following to ${name}|success`); + } + else { + await UserManager.followUser(address); + setFollowed(true); + setAlert(`Now you're following ${name}|success`); + } + } + catch(error) { + setAlert(error.message); + } + finally { + setLoading(false); + } + } + + const toggleBlock = async () => { + try { + setLoading(true); + if (isBlocked) { + await UserManager.unblockUser(address); + setIsBlocked(false); + setAlert(`You unblocked all activity from ${name}|success`); + } + else { + await UserManager.blockUser(address); + setIsBlocked(true); + setAlert(`You blocked all activity from ${name}|success`); + } + } + catch(error) { + setAlert(error.message); + } + finally { + setLoading(false); + } + } + const bannerContent = @@ -451,7 +586,7 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { }/> - { (walletAddress === address) && + { (walletAddress.toLowerCase() === address.toLowerCase()) && { ref={actionsAnchor} onClick={handleActionsOpen} className={styles.actionButton} - color="secondary" - disabled={processing}> + color="secondary"> { transformOrigin={{ vertical: "top", horizontal: "right" }} onClose={handleActionsClose} open={actionsOpen}> - {!edit && + {!isOwner && isBlocked && + handleAction('unblock')}> + + + + Unblock + + } + {!isOwner && !isBlocked && + handleAction('block')}> + + + + Block + + } + {!edit && isOwner && handleAction('edit')}> @@ -478,7 +628,7 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { Edit } - {edit && + {edit && isOwner && handleAction('cancel')}> @@ -486,7 +636,7 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { Cancel } - {edit && + {edit && isOwner && handleAction('save')}> @@ -532,6 +682,21 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { + { !loading && !isOwner && + + { + isBlocked? + : } label={isBlocked? "Unblock" : "Block"} onClick={toggleBlock}/> + : + imBlocked? + } label="Blocked you" color="secondary"/> + : + isFollower && } label="Follows you" color="primary"/> + } + + { !(isBlocked || imBlocked) && : } label={isFollowed? "Unfollow" : "Follow"} onClick={toggleFollow}/> } + + } { edit && } @@ -587,7 +752,7 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { - {/* Temporarily disabling until functionality is available + { Followers @@ -601,14 +766,18 @@ const ProfileCard = ({ address, identity, setUpperLoading, setAlert }) => { {loading ? : following } - */} + } + + {/* Temporarily disabling until functionality is available */} }/> + }/> + }/> > diff --git a/src/components/share/Share.jsx b/src/components/share/Share.jsx deleted file mode 100644 index 2fb45df..0000000 --- a/src/components/share/Share.jsx +++ /dev/null @@ -1,141 +0,0 @@ -import "./share.css"; -import { AttachFileTwoTone } from "@material-ui/icons"; -import { useRef, useState } from "react"; -import profileImg from '../../assets/profile-pic.jpg'; -import { useAppContext } from '../../context/AppContext'; - -import Snackbar from '@material-ui/core/Snackbar'; -import MuiAlert from '@material-ui/lab/Alert'; -import PostManager from "../../services/PostManager" - -function Alert(props) { - return ; -} - -export default function Share({reloadPosts}) { - const DEFAULT_BTN_LABEL = 'Share' - const EMPTY_IMAGE = '0x0000000000000000000000000000000000000000000000000000000000000000'; - const EMPTY_TEXT = '0x0000000000000000000000000000000000000000000000000000000000000000'; - const [selectedFile, setSelectedFile] = useState(); - const [contents, setContents] = useState(''); - const [btnLabel, setBtnLabel] = useState(DEFAULT_BTN_LABEL); - const [alert, setAlert] = useState(false); - const [btnEnabled, setBtnEnabled] = useState(false); - const [shareError, setShareError] = useState(undefined); - const { identity } = useAppContext(); - - const fileInputRef = useRef() - - const onFileChange = event => { - let fileToUpload = event.target.files[0]; - if(fileToUpload.type.startsWith('image') || fileToUpload.type.startsWith('video') ) { - if (fileToUpload.size > 100 * 1024 * 1024){ - alert('Point Social only supports image and video until 100 MB. Please change to a smaller image or video file!') - } - setSelectedFile(event.target.files[0]); - setBtnEnabled(true); - } else { - alert('Point Social only supports image and video uploads for now. Please change to an image or video file!') - } - }; - - const handleAlert = (event, reason) => { - if (reason === 'clickaway') { - return; - } - setAlert(false); - }; - - const onContentsChange = event => { - let newContents = event.target.value; - setContents(newContents) - setBtnEnabled(newContents && newContents.length > 0) - } - - const setSaving = (saving) => { - setBtnEnabled(!saving); - saving ? setBtnLabel('Saving...') : setBtnLabel(DEFAULT_BTN_LABEL); - } - - const submitHandler = async (e) => { - e.preventDefault(); - setSaving(true); - - try { - // Save the post content to the storage layer and keep the storage id - let {data: storageId} = (contents && contents.trim().length > 0)? await window.point.storage.putString({data: contents}) : { data: EMPTY_TEXT }; - let imageId = EMPTY_IMAGE; - if(selectedFile){ - const formData = new FormData() - formData.append("postfile", selectedFile); - const res = await window.point.storage.postFile(formData); - imageId = res.data; - } - // Save the post contents storage id in the PoinSocial Smart Contract - await PostManager.addPost(storageId, imageId) - await reloadPosts(); - setSaving(false); - setContents(''); - setSelectedFile(); - fileInputRef.current.value = null - setBtnEnabled(false); - } catch (e) { - console.error('Error sharing post: ', e.message); - setSaving(false); - setContents(''); - setSelectedFile(); - fileInputRef.current.value = null - setBtnEnabled(false); - setShareError(e); - setAlert(true); - } - }; - - return ( - - - - - - - - - - - - - - - - - {btnLabel} - - - - - - Error sharing post: {shareError && shareError.message}. Did you deploy the contract sucessfully? - - - - ); -} diff --git a/src/components/share/share.css b/src/components/share/share.css deleted file mode 100644 index 55035ed..0000000 --- a/src/components/share/share.css +++ /dev/null @@ -1,97 +0,0 @@ - .share { - width: 100%; - border-radius: 6px; - -webkit-box-shadow: 0px 0px 16px -8px rgba(172, 173, 181, 0.68); - box-shadow: 0px 0px 16px -8px rgba(172, 173, 181, 0.68); - } - - .shareWrapper { - padding: 15px; - } - - .shareTop { - display: flex; - align-items: center; - } - - .shareProfileImg { - width: 50px; - height: 50px; - border-radius: 50%; - object-fit: cover; - margin-right: 10px; - border:1px solid #dee0e6; - } - - .shareInput { - border: none; - width: 80%; - } - - .shareInput:focus { - outline: none; - } - - .shareHr { - margin: 20px 0; - background:#dce2ea; - height: 1px; - border:none; - } - - .shareBottom { - display: flex; - align-items: center; - justify-content: space-between; - } - - .shareOptions{ - display: flex; - /* margin-left: 20px; */ - } - - .shareOption{ - display: flex; - align-items: center; - margin-right: 15px; - cursor: pointer; - } - - .shareIcon{ - font-size: 18px; - margin-right: 3px; - } - - .shareOptionText{ - font-size: 14px; - font-weight: 500; - } - - .shareButton{ - border: none; - padding: 7px; - border-radius: 5px; - background-color: #1C385B; - font-weight: 500; - cursor: pointer; - color: white; - width:80px; - } - - .shareImgContainer{ - padding: 0 20px 10px 20px; - position: relative; - } - - .shareImg{ - width: 100%; - object-fit: cover; - } - - .shareCancelImg{ - position: absolute; - top: 0; - right: 20px; - cursor: pointer; - opacity: 0.7; - } \ No newline at end of file diff --git a/src/components/topbar/Topbar.jsx b/src/components/topbar/Topbar.jsx deleted file mode 100644 index 6a1996d..0000000 --- a/src/components/topbar/Topbar.jsx +++ /dev/null @@ -1,43 +0,0 @@ -import "./topbar.css"; -import { useAppContext } from '../../context/AppContext'; -import { Link } from "wouter"; -import pointlogo from '../../assets/pointlogowhite.png'; - -import Avatar from '@material-ui/core/Avatar'; - -export default function Topbar() { - const { walletAddress } = useAppContext(); - const { identity } = useAppContext(); - const { profile } = useAppContext(); - - return ( - - - - - - - Point Social - - - - - - - - - - - - - { walletAddress && profile && - - } - - - - ); -} diff --git a/src/components/topbar/topbar.css b/src/components/topbar/topbar.css deleted file mode 100644 index a4a5435..0000000 --- a/src/components/topbar/topbar.css +++ /dev/null @@ -1,100 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=Bungee+Inline&display=swap'); - -.topbarContainer { - height: 50px; - width: 100%; - background-color: #1c385b; - display: flex; - align-items: center; - position: sticky; - top: 0; - z-index: 999; - color:white; - } - - .topbarLeft { - margin-left: 10px; - flex: 3; - } - - .logo { - font-size: 24px; - margin-left: 5px; - font-weight: bold; - color: white; - cursor: pointer; - } - - .topbarCenter { - flex: 5; - } - - .searchbar { - width: 100%; - height: 30px; - background-color: white; - border-radius: 30px; - display: flex; - align-items: center; - } - - .searchIcon { - font-size: 20px !important; - margin-left: 10px; - } - - .searchInput { - border: none; - width: 70%; - } - - .searchInput:focus { - outline: none; - } - - .topbarRight { - flex: 4; - display: flex; - align-items: center; - justify-content: space-around; - color: white; - } - - .topbarLink { - margin-right: 10px; - font-size: 14px; - cursor: pointer; - } - - .topbarIcons { - display: flex; - } - - .topbarIconItem { - margin-right: 15px; - cursor: pointer; - position: relative; - } - - .topbarIconBadge { - width: 15px; - height: 15px; - background-color: red; - border-radius: 50%; - color: white; - position: absolute; - top: -5px; - right: -5px; - display: flex; - align-items: center; - justify-content: center; - font-size: 12px; - } - - .topbarImg { - width: 40px; - height: 40px; - border-radius: 50%; - object-fit: cover; - cursor: pointer; - } diff --git a/src/components/user/UserItem.jsx b/src/components/user/UserItem.jsx new file mode 100644 index 0000000..c1fcbb4 --- /dev/null +++ b/src/components/user/UserItem.jsx @@ -0,0 +1,69 @@ +import { useState, useEffect } from "react"; +import { useAppContext } from '../../context/AppContext'; +import { makeStyles } from '@material-ui/core/styles'; + +import ListItem from '@material-ui/core/ListItem'; +import Divider from '@material-ui/core/Divider'; +import ListItemText from '@material-ui/core/ListItemText'; +import ListItemAvatar from '@material-ui/core/ListItemAvatar'; +import UserAvatar from "../avatar/UserAvatar"; + +import point from "../../services/PointSDK"; +import UserManager from "../../services/UserManager"; + +const useStyles = makeStyles((theme) => ({ + root: { + cursor:'pointer', + }, +})); + +const EMPTY = '0x0000000000000000000000000000000000000000000000000000000000000000'; + +const UserItem = ({address}) => { + + const styles = useStyles(); + const [loading, setLoading] = useState(false); + const [name, setName] = useState(''); + const [about, setAbout] = useState(''); + + const { walletAddress, profile, identity } = useAppContext(); + + useEffect(() => { + loadUser(); + }, []); + + const loadUser = async () => { + setLoading(true); + if (address.toString().toLowerCase() === walletAddress.toString().toLowerCase()) { + setName((profile && profile.displayName) || identity); + setAbout(profile.displayAbout || "Hey I'm using Point Social!"); + } + else { + try { + const profile = await UserManager.getProfile(address); + const { identity } = await point.ownerToIdentity(address); + const name = (profile[0] === EMPTY)? identity : await point.getString(profile[0], { encoding: 'utf-8' }); + const about = (profile[2] === EMPTY)? "Hey I'm using Point Social!" : await point.getString(profile[2], {encoding: 'utf-8'}); + setName(name); + setAbout(about); + } + catch(error) {} + } + setLoading(false); + } + + return ( + <> + + + window.open(`/profile/${address}`, "_blank") }}/> + + + + + > + ); + +}; + +export default UserItem \ No newline at end of file diff --git a/src/components/user/UserList.jsx b/src/components/user/UserList.jsx new file mode 100644 index 0000000..03f060d --- /dev/null +++ b/src/components/user/UserList.jsx @@ -0,0 +1,87 @@ +import { useEffect, useState, useRef } from "react"; +import { makeStyles } from '@material-ui/core/styles'; +import { useAppContext } from '../../context/AppContext'; + +import CircularProgressWithIcon from "../../components/generic/CircularProgressWithIcon"; + +import {Box, + Divider, + List, + Typography, + } from '@material-ui/core'; + +import Skeleton from '@material-ui/lab/Skeleton'; + +import InboxOutlinedIcon from '@material-ui/icons/InboxOutlined'; +import RichTextField from '../generic/RichTextField'; +import SendOutlinedIcon from '@material-ui/icons/SendOutlined'; +import IconButton from '@material-ui/core/IconButton'; +import SmsOutlinedIcon from '@material-ui/icons/SmsOutlined'; + +import point from "../../services/PointSDK"; +import UserManager from "../../services/UserManager"; +import EventConstants from "../../events"; + +import UserItem from "./UserItem"; + +const useStyles = makeStyles((theme) => ({ + backdrop: { + position: "absolute", + zIndex: theme.zIndex.drawer - 1, + opacity: 0.9 + }, + root: { + width: '100%', + height: '100%', + backgroundColor: theme.palette.background.paper, + }, + inline: { + display: 'inline', + }, + empty: { + padding: theme.spacing(2, 2), + display: "flex", + flexDirection: "column", + alignItems:"center", + justifyContent: "center", + marginBottom: theme.spacing(6) + }, + commentBox: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center' + }, + list: { + minHeight: '50vh' + } +})); + +const UserList = ({users}) => { + + const styles = useStyles(); + return ( + + { + (users.length === 0) + ? + + + + No users yet. + + + : + + { + users.map((user) => ( + + + )) + } + + } + + ) +} + +export default UserList \ No newline at end of file diff --git a/src/context/AppContext.js b/src/context/AppContext.js index 05bd95a..0da9926 100644 --- a/src/context/AppContext.js +++ b/src/context/AppContext.js @@ -10,6 +10,7 @@ const events = new EventManager(); const defaultContext = { walletAddress: undefined, deployer : false, + isGateWay: false, walletError: undefined, identity: undefined, profile: undefined, @@ -32,7 +33,7 @@ export const ProvideAppContext = ({ children }) => { const [, setLocation] = useLocation(); const [profile, setUserProfile] = useState(); const [deployer, setDeployer] = useState(false); - const [processing, setProcessing] = useState(false); + const [processing, setProcessing] = useState(point.isGateway() || false); useEffect(() => { (async () => { @@ -70,6 +71,7 @@ export const ProvideAppContext = ({ children }) => { const context = { walletAddress, deployer, + isGateway : point.isGateway(), walletError, identity, profile, diff --git a/src/events.js b/src/events.js index a27642a..3dc1210 100644 --- a/src/events.js +++ b/src/events.js @@ -14,6 +14,12 @@ const EventConstants = { Feed: "1", Post: "2", Comment: "3", + }, + FollowAction: { + Follow : "0", + UnFollow : "1", + Block : "2", + UnBlock : "3" } } diff --git a/src/pages/home/Home.jsx b/src/pages/home/Home.jsx index e621ae7..f9877da 100644 --- a/src/pages/home/Home.jsx +++ b/src/pages/home/Home.jsx @@ -1,81 +1,148 @@ -import Appbar from '../../components/topbar/Appbar'; -import Footer from '../../components/footer/Footer'; +import Appbar from "../../components/topbar/Appbar"; +import Footer from "../../components/footer/Footer"; -import { useState } from 'react'; +import { useState } from "react"; import { useAppContext } from '../../context/AppContext'; import { makeStyles } from '@material-ui/core/styles'; -import { Backdrop, CircularProgress, Snackbar, Container } from '@material-ui/core'; +import { Backdrop, + Button, + CircularProgress, + Snackbar, + SnackbarContent, + Container } from '@material-ui/core'; -import CircularProgressWithIcon from '../../components/generic/CircularProgressWithIcon'; -import ShareCard from '../../components/share/ShareCard'; -import Feed from '../../components/feed/Feed'; -import Alert from '../../components/generic/Alert'; +import Tabs from '@material-ui/core/Tabs'; +import Tab from '@material-ui/core/Tab'; +import TabPanel from '../../components/tabs/TabPanel'; +import Tooltip from '@material-ui/core/Tooltip'; + +import DiscoverFeed from '../../components/feed/DiscoverFeed'; +import FollowFeed from '../../components/feed/FollowFeed'; +import FreshFeed from '../../components/feed/FreshFeed'; +import TopFeed from '../../components/feed/TopFeed'; + +import ExploreOutlinedIcon from '@material-ui/icons/ExploreOutlined'; +import PersonPinCircleOutlinedIcon from '@material-ui/icons/PersonPinCircleOutlined'; +import EcoOutlinedIcon from '@material-ui/icons/EcoOutlined'; +import EmojiEventsOutlinedIcon from '@material-ui/icons/EmojiEventsOutlined'; + +import CircularProgressWithIcon from "../../components/generic/CircularProgressWithIcon"; +import ShareCard from "../../components/share/ShareCard"; +import Feed from "../../components/feed/Feed"; +import Alert from "../../components/generic/Alert"; import AccountBalanceWalletOutlinedIcon from '@material-ui/icons/AccountBalanceWalletOutlined'; + const useStyles = makeStyles((theme) => ({ - root: { - height: '100%', - padding: 0, - margin: 0, - }, - container: { - padding: theme.spacing(2, 2), - display: 'flex', - minHeight: '100%', - flexDirection: 'column', - justifyContent: 'center', - maxWidth: '900px', - }, - backdrop: { - zIndex: theme.zIndex.drawer + 1, - }, + root: { + height: "100%", + padding: 0, + margin: 0, + }, + container: { + padding: theme.spacing(2, 2), + display: "flex", + minHeight: "100%", + flexDirection: "column", + justifyContent: "center", + maxWidth: '900px', + }, + backdrop: { + zIndex: theme.zIndex.drawer + 1, + }, + tab: { + padding: 0, + margin: 0, + }, + tabpanel: { + padding: 0, + } })); -const Home = () => { - const [loading, setLoading] = useState(false); - const [alert, setAlert] = useState(''); - const { walletAddress } = useAppContext(); +function a11yProps(index) { + return { + id: `scrollable-prevent-tab-${index}`, + 'aria-controls': `scrollable-prevent-tabpanel-${index}`, + }; +} - const styles = useStyles(); +const Home = () => { + const [loading, setLoading] = useState(false); + const [alert, setAlert] = useState(""); + const { walletAddress, isGateway } = useAppContext(); + const [tabIndex, setTabIndex] = useState(0); - const handleAlert = (event, reason) => { - if (reason === 'clickaway') { - return; - } - setAlert(''); - }; + const styles = useStyles(); + + const handleAlert = (event, reason) => { + if (reason === 'clickaway') { + return; + } + setAlert(""); + }; - return ( - - - {walletAddress ? ( - - ) : ( - } - props={{ color: 'inherit' }} - /> - )} - - {walletAddress && ( - <> - - - - - - - > - )} - - - {alert.split('|')[0]} - - - - ); -}; + const handleChange = (event, newIndex) => { + setTabIndex(newIndex); + }; + + return ( + + { + !loading && + + Download + }/> + + } + + { + walletAddress? + : + } props={{color : "inherit"}} /> + } + + { + walletAddress && + <> + + + + } aria-label="discover" {...a11yProps(0)} /> + } aria-label="following" {...a11yProps(1)}/> + } aria-label="fresh" {...a11yProps(2)} /> + } aria-label="top" {...a11yProps(3)}/> + + + + + + + + + + + + + + + + + > + } + + { alert.split("|")[0] } + + + ); +} -export default Home; +export default Home \ No newline at end of file diff --git a/src/pages/post/Post.jsx b/src/pages/post/Post.jsx index 31cdaad..0421c86 100644 --- a/src/pages/post/Post.jsx +++ b/src/pages/post/Post.jsx @@ -8,7 +8,10 @@ import PostManager from '../../services/PostManager'; import CircularProgress from '@material-ui/core/CircularProgress'; import Backdrop from '@material-ui/core/Backdrop'; +import Button from '@material-ui/core/Button'; import Snackbar from '@material-ui/core/Snackbar'; +import SnackbarContent from '@material-ui/core/SnackbarContent'; + import MuiAlert from '@material-ui/lab/Alert'; import CircularProgressWithIcon from "../../components/generic/CircularProgressWithIcon"; @@ -46,7 +49,7 @@ const Post = () => { const [alert, setAlert] = useState(""); const [post, setPost] = useState(); - const { walletAddress, events } = useAppContext(); + const { walletAddress, isGateway, events } = useAppContext(); const styles = useStyles(); @@ -143,6 +146,16 @@ const Post = () => { return ( { walletAddress && } + { + !loading && + + Download + }/> + + } { walletAddress? diff --git a/src/pages/profile/Profile.jsx b/src/pages/profile/Profile.jsx index d790e44..0891f6b 100644 --- a/src/pages/profile/Profile.jsx +++ b/src/pages/profile/Profile.jsx @@ -8,7 +8,10 @@ import CircularProgress from '@material-ui/core/CircularProgress'; import CircularProgressWithIcon from "../../components/generic/CircularProgressWithIcon"; import Backdrop from '@material-ui/core/Backdrop'; +import Button from '@material-ui/core/Button'; import Snackbar from '@material-ui/core/Snackbar'; +import SnackbarContent from '@material-ui/core/SnackbarContent'; + import MuiAlert from '@material-ui/lab/Alert'; import Box from '@material-ui/core/Box'; @@ -41,7 +44,7 @@ const Profile = () => { const [identity, setIdentity] = useState(undefined); const [address, setAddress] = useState(undefined); - const { walletAddress } = useAppContext(); + const { walletAddress, isGateway } = useAppContext(); const styles = useStyles(); @@ -98,6 +101,16 @@ const Profile = () => { } props={{color : "inherit"}} /> } + { + !loading && + + Download + }/> + + } {walletAddress && <> { (address && identity)? <> diff --git a/src/services/PointSDK.js b/src/services/PointSDK.js index c87ddb1..a9bd779 100644 --- a/src/services/PointSDK.js +++ b/src/services/PointSDK.js @@ -1,8 +1,8 @@ const POINT_TIMEOUT = 30 * 1000; const MAX_TIMEOUT = 600 * 1000; -const DEBUG = false; -const DISPLAY_ERRORS = false; +const DEBUG = true; +const DISPLAY_ERRORS = true; class PointSDK { @@ -46,6 +46,11 @@ class PointSDK { return data; } + static isGateway() { + const point = PointSDK._getPoint(); + return point.isGateway; + } + /************** WALLET FUNCTIONS **************/ static getWalletAddress = async () => PointSDK._callSDKFunction('wallet', 'address'); // OK diff --git a/src/services/PostManager.js b/src/services/PostManager.js index cb7d38f..28f58be 100644 --- a/src/services/PostManager.js +++ b/src/services/PostManager.js @@ -4,7 +4,7 @@ const EMPTY = '0x0000000000000000000000000000000000000000'; class PostManager { static getPost = async (postId) => point.contractCall("PointSocial", "getPostById", [postId]); - static isFlaggedPost = async (postId) => point.contractCall("PointSocial", "postIsFlagged", [postId]); + static postIsFlagged = async (postId) => point.contractCall("PointSocial", "postIsFlagged", [postId]); static addPost = async (contentId, imageId) => point.contractCall("PointSocial", "addPost", [ (contentId) ? contentId : EMPTY, @@ -14,8 +14,8 @@ class PostManager { static editPost = async (postId, contentId, imageId) => { return point.contractCall("PointSocial", "editPost", [ postId, - (contentId) ? contentId : EMPTY, - (imageId) ? imageId : EMPTY + (contentId ? contentId : EMPTY), + (imageId ? imageId : EMPTY) ]); } static flagPost = async (postId) => point.contractCall("PointSocial", "flagPost", [postId]); @@ -23,8 +23,9 @@ class PostManager { static addDislikeToPost = async (postId) => point.contractSend("PointSocial", "addDislikeToPost", [postId]); static getAllPostsByOwnerLength = async (account) => point.contractCall("PointSocial", "getAllPostsByOwnerLength", [account]); static getAllPostsLength = async () => point.contractCall("PointSocial", "getAllPostsLength", []); + static getLastPostId = async () => point.contractCall("PointSocial", "getLastPostId", []); static getPaginatedPostsByOwner = async (account, length, amount) => point.contractCall("PointSocial", "getPaginatedPostsByOwner", [account, length, amount]); - static getPaginatedPosts = async (length, amount) => point.contractCall("PointSocial", "getPaginatedPosts", [length, amount]); + static getPaginatedPosts = async (length, amount, type = 2) => point.contractCall("PointSocial", "getPaginatedPosts", [length, amount, type]); static checkLikeToPost = async (postId) => point.contractCall("PointSocial", "checkLikeToPost", [postId]); } diff --git a/src/services/UserManager.js b/src/services/UserManager.js index 5ae355c..df6010a 100644 --- a/src/services/UserManager.js +++ b/src/services/UserManager.js @@ -3,6 +3,17 @@ import point from "./PointSDK" class UserManager { static getProfile = async (userAddress) => point.contractCall("PointSocial", "getProfile", [userAddress]); static setProfile = async (displayName, displayLocation, displayAbout, avatar, banner) => point.contractCall("PointSocial", "setProfile", [displayName, displayLocation, displayAbout, avatar, banner]); + static isFollowing = async (owner, user) => point.contractCall("PointSocial", "isFollowing", [owner, user]); + static followUser = async (user) => point.contractCall("PointSocial", "followUser", [user]); + static unfollowUser = async (user) => point.contractCall("PointSocial", "unfollowUser", [user]); + static blockUser = async (user) => point.contractCall("PointSocial", "blockUser", [user]); + static unblockUser = async (user) => point.contractCall("PointSocial", "unBlockUser", [user]); + static isBlocked = async (owner, user) => point.contractCall("PointSocial", "isBlocked", [owner, user]); + static blockList = async () => point.contractCall("PointSocial", "blockList", []); + static followingList = async (user) => point.contractCall("PointSocial", "followingList", [user]); + static followersList = async (user) => point.contractCall("PointSocial", "followersList", [user]); + static followingCount = async (user) => point.contractCall("PointSocial", "followingCount", [user]); + static followersCount = async (user) => point.contractCall("PointSocial", "followersCount", [user]); } export default UserManager diff --git a/tests/unit/smartcontracts/PointSocial.js b/tests/unit/smartcontracts/PointSocial.js index 034e30e..9fe1048 100644 --- a/tests/unit/smartcontracts/PointSocial.js +++ b/tests/unit/smartcontracts/PointSocial.js @@ -41,24 +41,41 @@ describe('PointSocial contract', function () { await upgrades.upgradeProxy(pointSocial.address, socialFactoryDeployer); }); - it('Should not upgrade the proxy by a non-deployer', async function () { - await identityContract.setDevMode(true); - await identityContract.register( - handle, - owner.address, - '0xed17268897bbcb67127ed550cee2068a15fdb6f69097eebeb6e2ace46305d1ce', - '0xe1e032c91d4c8fe6bab1f198871dbafb8842f073acff8ee9b822f748b180d7eb' - ); - - const factory = await ethers.getContractFactory('PointSocial'); - let socialFactoryDeployer = factory.connect(addr1); - await expect( - upgrades.upgradeProxy(pointSocial.address, socialFactoryDeployer) - ).to.be.revertedWith('ERROR_NOT_DEPLOYER'); + describe("Testing deployment functions", function () { + + it("Should upgrade the proxy by a deployer", async function () { + await identityContract.setDevMode(true); + await identityContract.register( + handle, + owner.address, + '0xed17268897bbcb67127ed550cee2068a15fdb6f69097eebeb6e2ace46305d1ce', + '0xe1e032c91d4c8fe6bab1f198871dbafb8842f073acff8ee9b822f748b180d7eb'); + await identityContract.addIdentityDeployer(handle, addr1.address); + const factory = await ethers.getContractFactory("PointSocial"); + let socialFactoryDeployer = factory.connect(addr1); + + await upgrades.upgradeProxy(pointSocial.address, socialFactoryDeployer); + }); + + it("Should not upgrade the proxy by a non-deployer", async function () { + await identityContract.setDevMode(true); + await identityContract.register( + handle, + owner.address, + '0xed17268897bbcb67127ed550cee2068a15fdb6f69097eebeb6e2ace46305d1ce', + '0xe1e032c91d4c8fe6bab1f198871dbafb8842f073acff8ee9b822f748b180d7eb'); + + const factory = await ethers.getContractFactory("PointSocial"); + let socialFactoryDeployer = factory.connect(addr1); + await expect( + upgrades.upgradeProxy(pointSocial.address, socialFactoryDeployer) + ).to.be.revertedWith('ERROR_NOT_DEPLOYER'); + }); + }); }); - /*describe("Testing migrator functions", function () { + describe("Testing migrator functions", function () { it("User can add migrator", async function () { await pointSocial.addMigrator( addr1.address @@ -161,7 +178,7 @@ describe('PointSocial contract', function () { pointSocial.connect(addr2).addMigrator(addr2.address) ).to.be.revertedWith("Ownable: caller is not the owner"); }); - });*/ + }); describe('Testing user functions', function () { it('User can create post', async function () { @@ -259,10 +276,16 @@ describe('PointSocial contract', function () { const postCommentId = await pointSocial.commentIdsByPost(1, 0); const postComments = await pointSocial.commentById(postCommentId); - expect(postComments.contents).to.be.equal( - '0x0090916c0e6846d5dc8d22560e90782ded96e4efdeb53db214f612a54d4f5fbe' - ); - }); + const paginatedPosts = await pointSocial.getPaginatedPosts("5", "5", "1"); + + expect(paginatedPosts.length).to.be.equal(5); + }); + + it("Add comments to posts", async function () { + await pointSocial.addPost( + postContent, + postimage + ) it('Add dislike to posts', async () => { await pointSocial.addPost(postContent, postimage); @@ -354,4 +377,4 @@ describe('PointSocial contract', function () { ); }); }); -}); +}); \ No newline at end of file diff --git a/typechain/ERC1967UpgradeUpgradeable.d.ts b/typechain/ERC1967UpgradeUpgradeable.d.ts deleted file mode 100644 index 329ad08..0000000 --- a/typechain/ERC1967UpgradeUpgradeable.d.ts +++ /dev/null @@ -1,126 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ - -import { - ethers, - EventFilter, - Signer, - BigNumber, - BigNumberish, - PopulatedTransaction, - BaseContract, - ContractTransaction, -} from "ethers"; -import { BytesLike } from "@ethersproject/bytes"; -import { Listener, Provider } from "@ethersproject/providers"; -import { FunctionFragment, EventFragment, Result } from "@ethersproject/abi"; -import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; - -interface ERC1967UpgradeUpgradeableInterface extends ethers.utils.Interface { - functions: {}; - - events: { - "AdminChanged(address,address)": EventFragment; - "BeaconUpgraded(address)": EventFragment; - "Upgraded(address)": EventFragment; - }; - - getEvent(nameOrSignatureOrTopic: "AdminChanged"): EventFragment; - getEvent(nameOrSignatureOrTopic: "BeaconUpgraded"): EventFragment; - getEvent(nameOrSignatureOrTopic: "Upgraded"): EventFragment; -} - -export type AdminChangedEvent = TypedEvent< - [string, string] & { previousAdmin: string; newAdmin: string } ->; - -export type BeaconUpgradedEvent = TypedEvent<[string] & { beacon: string }>; - -export type UpgradedEvent = TypedEvent<[string] & { implementation: string }>; - -export class ERC1967UpgradeUpgradeable extends BaseContract { - connect(signerOrProvider: Signer | Provider | string): this; - attach(addressOrName: string): this; - deployed(): Promise; - - listeners, EventArgsObject>( - eventFilter?: TypedEventFilter - ): Array>; - off, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - on, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - once, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - removeListener, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - removeAllListeners, EventArgsObject>( - eventFilter: TypedEventFilter - ): this; - - listeners(eventName?: string): Array; - off(eventName: string, listener: Listener): this; - on(eventName: string, listener: Listener): this; - once(eventName: string, listener: Listener): this; - removeListener(eventName: string, listener: Listener): this; - removeAllListeners(eventName?: string): this; - - queryFilter, EventArgsObject>( - event: TypedEventFilter, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>>; - - interface: ERC1967UpgradeUpgradeableInterface; - - functions: {}; - - callStatic: {}; - - filters: { - "AdminChanged(address,address)"( - previousAdmin?: null, - newAdmin?: null - ): TypedEventFilter< - [string, string], - { previousAdmin: string; newAdmin: string } - >; - - AdminChanged( - previousAdmin?: null, - newAdmin?: null - ): TypedEventFilter< - [string, string], - { previousAdmin: string; newAdmin: string } - >; - - "BeaconUpgraded(address)"( - beacon?: string | null - ): TypedEventFilter<[string], { beacon: string }>; - - BeaconUpgraded( - beacon?: string | null - ): TypedEventFilter<[string], { beacon: string }>; - - "Upgraded(address)"( - implementation?: string | null - ): TypedEventFilter<[string], { implementation: string }>; - - Upgraded( - implementation?: string | null - ): TypedEventFilter<[string], { implementation: string }>; - }; - - estimateGas: {}; - - populateTransaction: {}; -} diff --git a/typechain/IBeaconUpgradeable.d.ts b/typechain/IBeaconUpgradeable.d.ts deleted file mode 100644 index 864f4a0..0000000 --- a/typechain/IBeaconUpgradeable.d.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ - -import { - ethers, - EventFilter, - Signer, - BigNumber, - BigNumberish, - PopulatedTransaction, - BaseContract, - ContractTransaction, - CallOverrides, -} from "ethers"; -import { BytesLike } from "@ethersproject/bytes"; -import { Listener, Provider } from "@ethersproject/providers"; -import { FunctionFragment, EventFragment, Result } from "@ethersproject/abi"; -import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; - -interface IBeaconUpgradeableInterface extends ethers.utils.Interface { - functions: { - "implementation()": FunctionFragment; - }; - - encodeFunctionData( - functionFragment: "implementation", - values?: undefined - ): string; - - decodeFunctionResult( - functionFragment: "implementation", - data: BytesLike - ): Result; - - events: {}; -} - -export class IBeaconUpgradeable extends BaseContract { - connect(signerOrProvider: Signer | Provider | string): this; - attach(addressOrName: string): this; - deployed(): Promise; - - listeners, EventArgsObject>( - eventFilter?: TypedEventFilter - ): Array>; - off, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - on, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - once, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - removeListener, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - removeAllListeners, EventArgsObject>( - eventFilter: TypedEventFilter - ): this; - - listeners(eventName?: string): Array; - off(eventName: string, listener: Listener): this; - on(eventName: string, listener: Listener): this; - once(eventName: string, listener: Listener): this; - removeListener(eventName: string, listener: Listener): this; - removeAllListeners(eventName?: string): this; - - queryFilter, EventArgsObject>( - event: TypedEventFilter, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>>; - - interface: IBeaconUpgradeableInterface; - - functions: { - implementation(overrides?: CallOverrides): Promise<[string]>; - }; - - implementation(overrides?: CallOverrides): Promise; - - callStatic: { - implementation(overrides?: CallOverrides): Promise; - }; - - filters: {}; - - estimateGas: { - implementation(overrides?: CallOverrides): Promise; - }; - - populateTransaction: { - implementation(overrides?: CallOverrides): Promise; - }; -} diff --git a/typechain/IERC1822ProxiableUpgradeable.d.ts b/typechain/IERC1822ProxiableUpgradeable.d.ts deleted file mode 100644 index e45277d..0000000 --- a/typechain/IERC1822ProxiableUpgradeable.d.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ - -import { - ethers, - EventFilter, - Signer, - BigNumber, - BigNumberish, - PopulatedTransaction, - BaseContract, - ContractTransaction, - CallOverrides, -} from "ethers"; -import { BytesLike } from "@ethersproject/bytes"; -import { Listener, Provider } from "@ethersproject/providers"; -import { FunctionFragment, EventFragment, Result } from "@ethersproject/abi"; -import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; - -interface IERC1822ProxiableUpgradeableInterface extends ethers.utils.Interface { - functions: { - "proxiableUUID()": FunctionFragment; - }; - - encodeFunctionData( - functionFragment: "proxiableUUID", - values?: undefined - ): string; - - decodeFunctionResult( - functionFragment: "proxiableUUID", - data: BytesLike - ): Result; - - events: {}; -} - -export class IERC1822ProxiableUpgradeable extends BaseContract { - connect(signerOrProvider: Signer | Provider | string): this; - attach(addressOrName: string): this; - deployed(): Promise; - - listeners, EventArgsObject>( - eventFilter?: TypedEventFilter - ): Array>; - off, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - on, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - once, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - removeListener, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - removeAllListeners, EventArgsObject>( - eventFilter: TypedEventFilter - ): this; - - listeners(eventName?: string): Array; - off(eventName: string, listener: Listener): this; - on(eventName: string, listener: Listener): this; - once(eventName: string, listener: Listener): this; - removeListener(eventName: string, listener: Listener): this; - removeAllListeners(eventName?: string): this; - - queryFilter, EventArgsObject>( - event: TypedEventFilter, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>>; - - interface: IERC1822ProxiableUpgradeableInterface; - - functions: { - proxiableUUID(overrides?: CallOverrides): Promise<[string]>; - }; - - proxiableUUID(overrides?: CallOverrides): Promise; - - callStatic: { - proxiableUUID(overrides?: CallOverrides): Promise; - }; - - filters: {}; - - estimateGas: { - proxiableUUID(overrides?: CallOverrides): Promise; - }; - - populateTransaction: { - proxiableUUID(overrides?: CallOverrides): Promise; - }; -} diff --git a/typechain/IIdentity.d.ts b/typechain/IIdentity.d.ts deleted file mode 100644 index 46c24a1..0000000 --- a/typechain/IIdentity.d.ts +++ /dev/null @@ -1,919 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ - -import { - ethers, - EventFilter, - Signer, - BigNumber, - BigNumberish, - PopulatedTransaction, - BaseContract, - ContractTransaction, - Overrides, - CallOverrides, -} from "ethers"; -import { BytesLike } from "@ethersproject/bytes"; -import { Listener, Provider } from "@ethersproject/providers"; -import { FunctionFragment, EventFragment, Result } from "@ethersproject/abi"; -import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; - -interface IIdentityInterface extends ethers.utils.Interface { - functions: { - "addIdentityDeployer(string,address)": FunctionFragment; - "canonical(string)": FunctionFragment; - "finishMigrations()": FunctionFragment; - "getCommPublicKeyByIdentity(string)": FunctionFragment; - "getDevMode()": FunctionFragment; - "getIdentityByOwner(address)": FunctionFragment; - "getMaxHandleLength()": FunctionFragment; - "getOracleAddress()": FunctionFragment; - "getOwnerByIdentity(string)": FunctionFragment; - "ikvGet(string,string)": FunctionFragment; - "ikvImportKV(string,string,string,string)": FunctionFragment; - "ikvPut(string,string,string,string)": FunctionFragment; - "isIdentityDeployer(string,address)": FunctionFragment; - "register(string,address,bytes32,bytes32)": FunctionFragment; - "registerVerified(string,address,bytes32,bytes32,bytes32,uint8,bytes32,bytes32)": FunctionFragment; - "removeIdentityDeployer(string,address)": FunctionFragment; - "setDevMode(bool)": FunctionFragment; - "setMaxHandleLength(uint256)": FunctionFragment; - "setOracleAddress(address)": FunctionFragment; - "transferIdentityOwnership(string,address)": FunctionFragment; - }; - - encodeFunctionData( - functionFragment: "addIdentityDeployer", - values: [string, string] - ): string; - encodeFunctionData(functionFragment: "canonical", values: [string]): string; - encodeFunctionData( - functionFragment: "finishMigrations", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "getCommPublicKeyByIdentity", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "getDevMode", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "getIdentityByOwner", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "getMaxHandleLength", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "getOracleAddress", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "getOwnerByIdentity", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "ikvGet", - values: [string, string] - ): string; - encodeFunctionData( - functionFragment: "ikvImportKV", - values: [string, string, string, string] - ): string; - encodeFunctionData( - functionFragment: "ikvPut", - values: [string, string, string, string] - ): string; - encodeFunctionData( - functionFragment: "isIdentityDeployer", - values: [string, string] - ): string; - encodeFunctionData( - functionFragment: "register", - values: [string, string, BytesLike, BytesLike] - ): string; - encodeFunctionData( - functionFragment: "registerVerified", - values: [ - string, - string, - BytesLike, - BytesLike, - BytesLike, - BigNumberish, - BytesLike, - BytesLike - ] - ): string; - encodeFunctionData( - functionFragment: "removeIdentityDeployer", - values: [string, string] - ): string; - encodeFunctionData(functionFragment: "setDevMode", values: [boolean]): string; - encodeFunctionData( - functionFragment: "setMaxHandleLength", - values: [BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "setOracleAddress", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "transferIdentityOwnership", - values: [string, string] - ): string; - - decodeFunctionResult( - functionFragment: "addIdentityDeployer", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "canonical", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "finishMigrations", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getCommPublicKeyByIdentity", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "getDevMode", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "getIdentityByOwner", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getMaxHandleLength", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getOracleAddress", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getOwnerByIdentity", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "ikvGet", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "ikvImportKV", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "ikvPut", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "isIdentityDeployer", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "registerVerified", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "removeIdentityDeployer", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "setDevMode", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "setMaxHandleLength", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "setOracleAddress", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "transferIdentityOwnership", - data: BytesLike - ): Result; - - events: { - "IKVSet(string,string,string,string)": EventFragment; - "IdentityDeployerChanged(string,address,bool)": EventFragment; - "IdentityOwnershipTransferred(string,address,address,uint256)": EventFragment; - "IdentityRegistered(string,address,tuple)": EventFragment; - }; - - getEvent(nameOrSignatureOrTopic: "IKVSet"): EventFragment; - getEvent(nameOrSignatureOrTopic: "IdentityDeployerChanged"): EventFragment; - getEvent( - nameOrSignatureOrTopic: "IdentityOwnershipTransferred" - ): EventFragment; - getEvent(nameOrSignatureOrTopic: "IdentityRegistered"): EventFragment; -} - -export type IKVSetEvent = TypedEvent< - [string, string, string, string] & { - identity: string; - key: string; - value: string; - version: string; - } ->; - -export type IdentityDeployerChangedEvent = TypedEvent< - [string, string, boolean] & { - identity: string; - deployer: string; - allowed: boolean; - } ->; - -export type IdentityOwnershipTransferredEvent = TypedEvent< - [string, string, string, BigNumber] & { - handle: string; - oldOwner: string; - newOwner: string; - date: BigNumber; - } ->; - -export type IdentityRegisteredEvent = TypedEvent< - [string, string, [string, string] & { part1: string; part2: string }] & { - handle: string; - identityOwner: string; - commPublicKey: [string, string] & { part1: string; part2: string }; - } ->; - -export class IIdentity extends BaseContract { - connect(signerOrProvider: Signer | Provider | string): this; - attach(addressOrName: string): this; - deployed(): Promise; - - listeners, EventArgsObject>( - eventFilter?: TypedEventFilter - ): Array>; - off, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - on, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - once, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - removeListener, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - removeAllListeners, EventArgsObject>( - eventFilter: TypedEventFilter - ): this; - - listeners(eventName?: string): Array; - off(eventName: string, listener: Listener): this; - on(eventName: string, listener: Listener): this; - once(eventName: string, listener: Listener): this; - removeListener(eventName: string, listener: Listener): this; - removeAllListeners(eventName?: string): this; - - queryFilter, EventArgsObject>( - event: TypedEventFilter, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>>; - - interface: IIdentityInterface; - - functions: { - addIdentityDeployer( - handle: string, - deployer: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - canonical( - anyCase: string, - overrides?: CallOverrides - ): Promise<[string] & { canonicalCase: string }>; - - finishMigrations( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - getCommPublicKeyByIdentity( - identity: string, - overrides?: CallOverrides - ): Promise< - [[string, string] & { part1: string; part2: string }] & { - commPublicKey: [string, string] & { part1: string; part2: string }; - } - >; - - getDevMode(overrides?: CallOverrides): Promise<[boolean]>; - - getIdentityByOwner( - owner: string, - overrides?: CallOverrides - ): Promise<[string] & { identity: string }>; - - getMaxHandleLength(overrides?: CallOverrides): Promise<[BigNumber]>; - - getOracleAddress(overrides?: CallOverrides): Promise<[string]>; - - getOwnerByIdentity( - identity: string, - overrides?: CallOverrides - ): Promise<[string] & { owner: string }>; - - ikvGet( - identity: string, - key: string, - overrides?: CallOverrides - ): Promise<[string] & { value: string }>; - - ikvImportKV( - identity: string, - key: string, - value: string, - version: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - ikvPut( - identity: string, - key: string, - value: string, - version: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - isIdentityDeployer( - handle: string, - deployer: string, - overrides?: CallOverrides - ): Promise<[boolean]>; - - register( - handle: string, - identityOwner: string, - commPublicKeyPart1: BytesLike, - commPublicKeyPart2: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - registerVerified( - handle: string, - identityOwner: string, - commPublicKeyPart1: BytesLike, - commPublicKeyPart2: BytesLike, - _hashedMessage: BytesLike, - _v: BigNumberish, - _r: BytesLike, - _s: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - removeIdentityDeployer( - handle: string, - deployer: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - setDevMode( - value: boolean, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - setMaxHandleLength( - value: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - setOracleAddress( - addr: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - transferIdentityOwnership( - handle: string, - newOwner: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - }; - - addIdentityDeployer( - handle: string, - deployer: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - canonical(anyCase: string, overrides?: CallOverrides): Promise; - - finishMigrations( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - getCommPublicKeyByIdentity( - identity: string, - overrides?: CallOverrides - ): Promise<[string, string] & { part1: string; part2: string }>; - - getDevMode(overrides?: CallOverrides): Promise; - - getIdentityByOwner(owner: string, overrides?: CallOverrides): Promise; - - getMaxHandleLength(overrides?: CallOverrides): Promise; - - getOracleAddress(overrides?: CallOverrides): Promise; - - getOwnerByIdentity( - identity: string, - overrides?: CallOverrides - ): Promise; - - ikvGet( - identity: string, - key: string, - overrides?: CallOverrides - ): Promise; - - ikvImportKV( - identity: string, - key: string, - value: string, - version: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - ikvPut( - identity: string, - key: string, - value: string, - version: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - isIdentityDeployer( - handle: string, - deployer: string, - overrides?: CallOverrides - ): Promise; - - register( - handle: string, - identityOwner: string, - commPublicKeyPart1: BytesLike, - commPublicKeyPart2: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - registerVerified( - handle: string, - identityOwner: string, - commPublicKeyPart1: BytesLike, - commPublicKeyPart2: BytesLike, - _hashedMessage: BytesLike, - _v: BigNumberish, - _r: BytesLike, - _s: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - removeIdentityDeployer( - handle: string, - deployer: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - setDevMode( - value: boolean, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - setMaxHandleLength( - value: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - setOracleAddress( - addr: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - transferIdentityOwnership( - handle: string, - newOwner: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - callStatic: { - addIdentityDeployer( - handle: string, - deployer: string, - overrides?: CallOverrides - ): Promise; - - canonical(anyCase: string, overrides?: CallOverrides): Promise; - - finishMigrations(overrides?: CallOverrides): Promise; - - getCommPublicKeyByIdentity( - identity: string, - overrides?: CallOverrides - ): Promise<[string, string] & { part1: string; part2: string }>; - - getDevMode(overrides?: CallOverrides): Promise; - - getIdentityByOwner( - owner: string, - overrides?: CallOverrides - ): Promise; - - getMaxHandleLength(overrides?: CallOverrides): Promise; - - getOracleAddress(overrides?: CallOverrides): Promise; - - getOwnerByIdentity( - identity: string, - overrides?: CallOverrides - ): Promise; - - ikvGet( - identity: string, - key: string, - overrides?: CallOverrides - ): Promise; - - ikvImportKV( - identity: string, - key: string, - value: string, - version: string, - overrides?: CallOverrides - ): Promise; - - ikvPut( - identity: string, - key: string, - value: string, - version: string, - overrides?: CallOverrides - ): Promise; - - isIdentityDeployer( - handle: string, - deployer: string, - overrides?: CallOverrides - ): Promise; - - register( - handle: string, - identityOwner: string, - commPublicKeyPart1: BytesLike, - commPublicKeyPart2: BytesLike, - overrides?: CallOverrides - ): Promise; - - registerVerified( - handle: string, - identityOwner: string, - commPublicKeyPart1: BytesLike, - commPublicKeyPart2: BytesLike, - _hashedMessage: BytesLike, - _v: BigNumberish, - _r: BytesLike, - _s: BytesLike, - overrides?: CallOverrides - ): Promise; - - removeIdentityDeployer( - handle: string, - deployer: string, - overrides?: CallOverrides - ): Promise; - - setDevMode(value: boolean, overrides?: CallOverrides): Promise; - - setMaxHandleLength( - value: BigNumberish, - overrides?: CallOverrides - ): Promise; - - setOracleAddress(addr: string, overrides?: CallOverrides): Promise; - - transferIdentityOwnership( - handle: string, - newOwner: string, - overrides?: CallOverrides - ): Promise; - }; - - filters: { - "IKVSet(string,string,string,string)"( - identity?: null, - key?: null, - value?: null, - version?: null - ): TypedEventFilter< - [string, string, string, string], - { identity: string; key: string; value: string; version: string } - >; - - IKVSet( - identity?: null, - key?: null, - value?: null, - version?: null - ): TypedEventFilter< - [string, string, string, string], - { identity: string; key: string; value: string; version: string } - >; - - "IdentityDeployerChanged(string,address,bool)"( - identity?: null, - deployer?: null, - allowed?: null - ): TypedEventFilter< - [string, string, boolean], - { identity: string; deployer: string; allowed: boolean } - >; - - IdentityDeployerChanged( - identity?: null, - deployer?: null, - allowed?: null - ): TypedEventFilter< - [string, string, boolean], - { identity: string; deployer: string; allowed: boolean } - >; - - "IdentityOwnershipTransferred(string,address,address,uint256)"( - handle?: string | null, - oldOwner?: string | null, - newOwner?: string | null, - date?: null - ): TypedEventFilter< - [string, string, string, BigNumber], - { handle: string; oldOwner: string; newOwner: string; date: BigNumber } - >; - - IdentityOwnershipTransferred( - handle?: string | null, - oldOwner?: string | null, - newOwner?: string | null, - date?: null - ): TypedEventFilter< - [string, string, string, BigNumber], - { handle: string; oldOwner: string; newOwner: string; date: BigNumber } - >; - - "IdentityRegistered(string,address,tuple)"( - handle?: null, - identityOwner?: null, - commPublicKey?: null - ): TypedEventFilter< - [string, string, [string, string] & { part1: string; part2: string }], - { - handle: string; - identityOwner: string; - commPublicKey: [string, string] & { part1: string; part2: string }; - } - >; - - IdentityRegistered( - handle?: null, - identityOwner?: null, - commPublicKey?: null - ): TypedEventFilter< - [string, string, [string, string] & { part1: string; part2: string }], - { - handle: string; - identityOwner: string; - commPublicKey: [string, string] & { part1: string; part2: string }; - } - >; - }; - - estimateGas: { - addIdentityDeployer( - handle: string, - deployer: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - canonical(anyCase: string, overrides?: CallOverrides): Promise; - - finishMigrations( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - getCommPublicKeyByIdentity( - identity: string, - overrides?: CallOverrides - ): Promise; - - getDevMode(overrides?: CallOverrides): Promise; - - getIdentityByOwner( - owner: string, - overrides?: CallOverrides - ): Promise; - - getMaxHandleLength(overrides?: CallOverrides): Promise; - - getOracleAddress(overrides?: CallOverrides): Promise; - - getOwnerByIdentity( - identity: string, - overrides?: CallOverrides - ): Promise; - - ikvGet( - identity: string, - key: string, - overrides?: CallOverrides - ): Promise; - - ikvImportKV( - identity: string, - key: string, - value: string, - version: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - ikvPut( - identity: string, - key: string, - value: string, - version: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - isIdentityDeployer( - handle: string, - deployer: string, - overrides?: CallOverrides - ): Promise; - - register( - handle: string, - identityOwner: string, - commPublicKeyPart1: BytesLike, - commPublicKeyPart2: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - registerVerified( - handle: string, - identityOwner: string, - commPublicKeyPart1: BytesLike, - commPublicKeyPart2: BytesLike, - _hashedMessage: BytesLike, - _v: BigNumberish, - _r: BytesLike, - _s: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - removeIdentityDeployer( - handle: string, - deployer: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - setDevMode( - value: boolean, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - setMaxHandleLength( - value: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - setOracleAddress( - addr: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - transferIdentityOwnership( - handle: string, - newOwner: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - }; - - populateTransaction: { - addIdentityDeployer( - handle: string, - deployer: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - canonical( - anyCase: string, - overrides?: CallOverrides - ): Promise; - - finishMigrations( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - getCommPublicKeyByIdentity( - identity: string, - overrides?: CallOverrides - ): Promise; - - getDevMode(overrides?: CallOverrides): Promise; - - getIdentityByOwner( - owner: string, - overrides?: CallOverrides - ): Promise; - - getMaxHandleLength( - overrides?: CallOverrides - ): Promise; - - getOracleAddress(overrides?: CallOverrides): Promise; - - getOwnerByIdentity( - identity: string, - overrides?: CallOverrides - ): Promise; - - ikvGet( - identity: string, - key: string, - overrides?: CallOverrides - ): Promise; - - ikvImportKV( - identity: string, - key: string, - value: string, - version: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - ikvPut( - identity: string, - key: string, - value: string, - version: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - isIdentityDeployer( - handle: string, - deployer: string, - overrides?: CallOverrides - ): Promise; - - register( - handle: string, - identityOwner: string, - commPublicKeyPart1: BytesLike, - commPublicKeyPart2: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - registerVerified( - handle: string, - identityOwner: string, - commPublicKeyPart1: BytesLike, - commPublicKeyPart2: BytesLike, - _hashedMessage: BytesLike, - _v: BigNumberish, - _r: BytesLike, - _s: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - removeIdentityDeployer( - handle: string, - deployer: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - setDevMode( - value: boolean, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - setMaxHandleLength( - value: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - setOracleAddress( - addr: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - transferIdentityOwnership( - handle: string, - newOwner: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - }; -} diff --git a/typechain/Identity.d.ts b/typechain/Identity.d.ts deleted file mode 100644 index 30f4c08..0000000 --- a/typechain/Identity.d.ts +++ /dev/null @@ -1,1401 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ - -import { - ethers, - EventFilter, - Signer, - BigNumber, - BigNumberish, - PopulatedTransaction, - BaseContract, - ContractTransaction, - Overrides, - PayableOverrides, - CallOverrides, -} from "ethers"; -import { BytesLike } from "@ethersproject/bytes"; -import { Listener, Provider } from "@ethersproject/providers"; -import { FunctionFragment, EventFragment, Result } from "@ethersproject/abi"; -import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; - -interface IdentityInterface extends ethers.utils.Interface { - functions: { - "addIdentityDeployer(string,address)": FunctionFragment; - "canonical(string)": FunctionFragment; - "finishMigrations()": FunctionFragment; - "getCommPublicKeyByIdentity(string)": FunctionFragment; - "getDevMode()": FunctionFragment; - "getIdentityByOwner(address)": FunctionFragment; - "getMaxHandleLength()": FunctionFragment; - "getOracleAddress()": FunctionFragment; - "getOwnerByIdentity(string)": FunctionFragment; - "identityList(uint256)": FunctionFragment; - "identityToCommPublicKey(string)": FunctionFragment; - "identityToOwner(string)": FunctionFragment; - "ikv(string,string)": FunctionFragment; - "ikvGet(string,string)": FunctionFragment; - "ikvImportKV(string,string,string,string)": FunctionFragment; - "ikvList(string,uint256)": FunctionFragment; - "ikvPut(string,string,string,string)": FunctionFragment; - "initialize()": FunctionFragment; - "isIdentityDeployer(string,address)": FunctionFragment; - "lowercaseToCanonicalIdentities(string)": FunctionFragment; - "migrationApplied()": FunctionFragment; - "owner()": FunctionFragment; - "ownerToIdentity(address)": FunctionFragment; - "proxiableUUID()": FunctionFragment; - "register(string,address,bytes32,bytes32)": FunctionFragment; - "registerVerified(string,address,bytes32,bytes32,bytes32,uint8,bytes32,bytes32)": FunctionFragment; - "removeIdentityDeployer(string,address)": FunctionFragment; - "renounceOwnership()": FunctionFragment; - "setDevMode(bool)": FunctionFragment; - "setMaxHandleLength(uint256)": FunctionFragment; - "setOracleAddress(address)": FunctionFragment; - "transferIdentityOwnership(string,address)": FunctionFragment; - "transferOwnership(address)": FunctionFragment; - "upgradeTo(address)": FunctionFragment; - "upgradeToAndCall(address,bytes)": FunctionFragment; - }; - - encodeFunctionData( - functionFragment: "addIdentityDeployer", - values: [string, string] - ): string; - encodeFunctionData(functionFragment: "canonical", values: [string]): string; - encodeFunctionData( - functionFragment: "finishMigrations", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "getCommPublicKeyByIdentity", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "getDevMode", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "getIdentityByOwner", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "getMaxHandleLength", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "getOracleAddress", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "getOwnerByIdentity", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "identityList", - values: [BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "identityToCommPublicKey", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "identityToOwner", - values: [string] - ): string; - encodeFunctionData(functionFragment: "ikv", values: [string, string]): string; - encodeFunctionData( - functionFragment: "ikvGet", - values: [string, string] - ): string; - encodeFunctionData( - functionFragment: "ikvImportKV", - values: [string, string, string, string] - ): string; - encodeFunctionData( - functionFragment: "ikvList", - values: [string, BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "ikvPut", - values: [string, string, string, string] - ): string; - encodeFunctionData( - functionFragment: "initialize", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "isIdentityDeployer", - values: [string, string] - ): string; - encodeFunctionData( - functionFragment: "lowercaseToCanonicalIdentities", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "migrationApplied", - values?: undefined - ): string; - encodeFunctionData(functionFragment: "owner", values?: undefined): string; - encodeFunctionData( - functionFragment: "ownerToIdentity", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "proxiableUUID", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "register", - values: [string, string, BytesLike, BytesLike] - ): string; - encodeFunctionData( - functionFragment: "registerVerified", - values: [ - string, - string, - BytesLike, - BytesLike, - BytesLike, - BigNumberish, - BytesLike, - BytesLike - ] - ): string; - encodeFunctionData( - functionFragment: "removeIdentityDeployer", - values: [string, string] - ): string; - encodeFunctionData( - functionFragment: "renounceOwnership", - values?: undefined - ): string; - encodeFunctionData(functionFragment: "setDevMode", values: [boolean]): string; - encodeFunctionData( - functionFragment: "setMaxHandleLength", - values: [BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "setOracleAddress", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "transferIdentityOwnership", - values: [string, string] - ): string; - encodeFunctionData( - functionFragment: "transferOwnership", - values: [string] - ): string; - encodeFunctionData(functionFragment: "upgradeTo", values: [string]): string; - encodeFunctionData( - functionFragment: "upgradeToAndCall", - values: [string, BytesLike] - ): string; - - decodeFunctionResult( - functionFragment: "addIdentityDeployer", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "canonical", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "finishMigrations", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getCommPublicKeyByIdentity", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "getDevMode", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "getIdentityByOwner", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getMaxHandleLength", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getOracleAddress", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getOwnerByIdentity", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "identityList", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "identityToCommPublicKey", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "identityToOwner", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "ikv", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "ikvGet", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "ikvImportKV", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "ikvList", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "ikvPut", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "initialize", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "isIdentityDeployer", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "lowercaseToCanonicalIdentities", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "migrationApplied", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "ownerToIdentity", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "proxiableUUID", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "registerVerified", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "removeIdentityDeployer", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "renounceOwnership", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "setDevMode", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "setMaxHandleLength", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "setOracleAddress", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "transferIdentityOwnership", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "transferOwnership", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "upgradeTo", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "upgradeToAndCall", - data: BytesLike - ): Result; - - events: { - "AdminChanged(address,address)": EventFragment; - "BeaconUpgraded(address)": EventFragment; - "IKVSet(string,string,string,string)": EventFragment; - "IdentityDeployerChanged(string,address,bool)": EventFragment; - "IdentityOwnershipTransferred(string,address,address,uint256)": EventFragment; - "IdentityRegistered(string,address,tuple)": EventFragment; - "OwnershipTransferred(address,address)": EventFragment; - "Upgraded(address)": EventFragment; - }; - - getEvent(nameOrSignatureOrTopic: "AdminChanged"): EventFragment; - getEvent(nameOrSignatureOrTopic: "BeaconUpgraded"): EventFragment; - getEvent(nameOrSignatureOrTopic: "IKVSet"): EventFragment; - getEvent(nameOrSignatureOrTopic: "IdentityDeployerChanged"): EventFragment; - getEvent( - nameOrSignatureOrTopic: "IdentityOwnershipTransferred" - ): EventFragment; - getEvent(nameOrSignatureOrTopic: "IdentityRegistered"): EventFragment; - getEvent(nameOrSignatureOrTopic: "OwnershipTransferred"): EventFragment; - getEvent(nameOrSignatureOrTopic: "Upgraded"): EventFragment; -} - -export type AdminChangedEvent = TypedEvent< - [string, string] & { previousAdmin: string; newAdmin: string } ->; - -export type BeaconUpgradedEvent = TypedEvent<[string] & { beacon: string }>; - -export type IKVSetEvent = TypedEvent< - [string, string, string, string] & { - identity: string; - key: string; - value: string; - version: string; - } ->; - -export type IdentityDeployerChangedEvent = TypedEvent< - [string, string, boolean] & { - identity: string; - deployer: string; - allowed: boolean; - } ->; - -export type IdentityOwnershipTransferredEvent = TypedEvent< - [string, string, string, BigNumber] & { - handle: string; - oldOwner: string; - newOwner: string; - date: BigNumber; - } ->; - -export type IdentityRegisteredEvent = TypedEvent< - [string, string, [string, string] & { part1: string; part2: string }] & { - handle: string; - identityOwner: string; - commPublicKey: [string, string] & { part1: string; part2: string }; - } ->; - -export type OwnershipTransferredEvent = TypedEvent< - [string, string] & { previousOwner: string; newOwner: string } ->; - -export type UpgradedEvent = TypedEvent<[string] & { implementation: string }>; - -export class Identity extends BaseContract { - connect(signerOrProvider: Signer | Provider | string): this; - attach(addressOrName: string): this; - deployed(): Promise; - - listeners, EventArgsObject>( - eventFilter?: TypedEventFilter - ): Array>; - off, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - on, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - once, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - removeListener, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - removeAllListeners, EventArgsObject>( - eventFilter: TypedEventFilter
{comment.contents}
{post?.contents}
Followers