feat: erc interface and split out access points to single module (#151)
* wip: compilant version of interface * refactor: split out access point to single module * test: fix mint call on hardhat tests * fix: remove auto approval from NewMint event
This commit is contained in:
parent
fbee0945fd
commit
df6fbea5c0
|
|
@ -0,0 +1,212 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.7;
|
||||
|
||||
import {FleekStrings} from "./util/FleekStrings.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
|
||||
error AccessPointNotExistent();
|
||||
error AccessPointAlreadyExists();
|
||||
error AccessPointScoreCannotBeLower();
|
||||
error MustBeAccessPointOwner();
|
||||
error InvalidTokenIdForAccessPoint();
|
||||
error AccessPointCreationStatusAlreadySet();
|
||||
|
||||
abstract contract FleekAccessPoints is Initializable {
|
||||
using FleekStrings for FleekAccessPoints.AccessPoint;
|
||||
|
||||
event NewAccessPoint(string apName, uint256 indexed tokenId, address indexed owner);
|
||||
event RemoveAccessPoint(string apName, uint256 indexed tokenId, address indexed owner);
|
||||
|
||||
event ChangeAccessPointScore(string apName, uint256 indexed tokenId, uint256 score, address indexed triggeredBy);
|
||||
|
||||
event ChangeAccessPointNameVerify(
|
||||
string apName,
|
||||
uint256 tokenId,
|
||||
bool indexed verified,
|
||||
address indexed triggeredBy
|
||||
);
|
||||
event ChangeAccessPointContentVerify(
|
||||
string apName,
|
||||
uint256 tokenId,
|
||||
bool indexed verified,
|
||||
address indexed triggeredBy
|
||||
);
|
||||
event ChangeAccessPointCreationStatus(
|
||||
string apName,
|
||||
uint256 tokenId,
|
||||
AccessPointCreationStatus status,
|
||||
address indexed triggeredBy
|
||||
);
|
||||
|
||||
/**
|
||||
* Creation status enums for access points
|
||||
*/
|
||||
enum AccessPointCreationStatus {
|
||||
DRAFT,
|
||||
APPROVED,
|
||||
REJECTED,
|
||||
REMOVED
|
||||
}
|
||||
|
||||
/**
|
||||
* The stored data for each AccessPoint.
|
||||
*/
|
||||
struct AccessPoint {
|
||||
uint256 tokenId;
|
||||
uint256 score;
|
||||
bool contentVerified;
|
||||
bool nameVerified;
|
||||
address owner;
|
||||
AccessPointCreationStatus status;
|
||||
}
|
||||
|
||||
mapping(string => AccessPoint) private _accessPoints;
|
||||
|
||||
mapping(uint256 => bool) private _autoApproval;
|
||||
|
||||
/**
|
||||
* @dev Checks if the AccessPoint exists.
|
||||
*/
|
||||
modifier requireAP(string memory apName) {
|
||||
if (_accessPoints[apName].owner == address(0)) revert AccessPointNotExistent();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev A view function to gether information about an AccessPoint.
|
||||
* It returns a JSON string representing the AccessPoint information.
|
||||
*/
|
||||
function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {
|
||||
AccessPoint storage _ap = _accessPoints[apName];
|
||||
return _ap.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev A view function to check if a AccessPoint is verified.
|
||||
*/
|
||||
function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {
|
||||
return _accessPoints[apName].nameVerified;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Increases the score of a AccessPoint registry.
|
||||
*/
|
||||
function increaseAccessPointScore(string memory apName) public requireAP(apName) {
|
||||
_accessPoints[apName].score++;
|
||||
emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Decreases the score of a AccessPoint registry if is greater than 0.
|
||||
*/
|
||||
function decreaseAccessPointScore(string memory apName) public requireAP(apName) {
|
||||
if (_accessPoints[apName].score == 0) revert AccessPointScoreCannotBeLower();
|
||||
_accessPoints[apName].score--;
|
||||
emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Add a new AccessPoint register for an app token.
|
||||
* The AP name should be a DNS or ENS url and it should be unique.
|
||||
*/
|
||||
function _addAccessPoint(uint256 tokenId, string memory apName) internal {
|
||||
if (_accessPoints[apName].owner != address(0)) revert AccessPointAlreadyExists();
|
||||
|
||||
emit NewAccessPoint(apName, tokenId, msg.sender);
|
||||
|
||||
if (_autoApproval[tokenId]) {
|
||||
// Auto Approval is on.
|
||||
_accessPoints[apName] = AccessPoint(
|
||||
tokenId,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
msg.sender,
|
||||
AccessPointCreationStatus.APPROVED
|
||||
);
|
||||
|
||||
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.APPROVED, msg.sender);
|
||||
} else {
|
||||
// Auto Approval is off. Should wait for approval.
|
||||
_accessPoints[apName] = AccessPoint(tokenId, 0, false, false, msg.sender, AccessPointCreationStatus.DRAFT);
|
||||
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.DRAFT, msg.sender);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Remove an AccessPoint registry for an app token.
|
||||
* It will also remove the AP from the app token APs list.
|
||||
*/
|
||||
function _removeAccessPoint(string memory apName) internal requireAP(apName) {
|
||||
if (msg.sender != _accessPoints[apName].owner) revert MustBeAccessPointOwner();
|
||||
_accessPoints[apName].status = AccessPointCreationStatus.REMOVED;
|
||||
uint256 tokenId = _accessPoints[apName].tokenId;
|
||||
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.REMOVED, msg.sender);
|
||||
emit RemoveAccessPoint(apName, tokenId, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates the `accessPointAutoApproval` settings on minted `tokenId`.
|
||||
*/
|
||||
function _setAccessPointAutoApproval(uint256 tokenId, bool _apAutoApproval) internal {
|
||||
_autoApproval[tokenId] = _apAutoApproval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set approval settings for an access point.
|
||||
* It will add the access point to the token's AP list, if `approved` is true.
|
||||
*/
|
||||
function _setApprovalForAccessPoint(uint256 tokenId, string memory apName, bool approved) internal {
|
||||
AccessPoint storage accessPoint = _accessPoints[apName];
|
||||
if (accessPoint.tokenId != tokenId) revert InvalidTokenIdForAccessPoint();
|
||||
if (accessPoint.status != AccessPointCreationStatus.DRAFT) revert AccessPointCreationStatusAlreadySet();
|
||||
|
||||
if (approved) {
|
||||
// Approval
|
||||
accessPoint.status = AccessPointCreationStatus.APPROVED;
|
||||
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.APPROVED, msg.sender);
|
||||
} else {
|
||||
// Not Approved
|
||||
accessPoint.status = AccessPointCreationStatus.REJECTED;
|
||||
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.REJECTED, msg.sender);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set the content verification of a AccessPoint registry.
|
||||
*/
|
||||
function _setAccessPointContentVerify(string memory apName, bool verified) internal requireAP(apName) {
|
||||
_accessPoints[apName].contentVerified = verified;
|
||||
emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set the name verification of a AccessPoint registry.
|
||||
*/
|
||||
function _setAccessPointNameVerify(string memory apName, bool verified) internal requireAP(apName) {
|
||||
_accessPoints[apName].nameVerified = verified;
|
||||
emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Get the AccessPoint token id.
|
||||
*/
|
||||
function _getAccessPointTokenId(string memory apName) internal view requireAP(apName) returns (uint256) {
|
||||
return _accessPoints[apName].tokenId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Get the Auto Approval setting for token id.
|
||||
*/
|
||||
function _getAccessPointAutoApproval(uint256 tokenId) internal view returns (bool) {
|
||||
return _autoApproval[tokenId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev This empty reserved space is put in place to allow future versions to add new
|
||||
* variables without shifting down storage in the inheritance chain.
|
||||
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
|
||||
*/
|
||||
uint256[49] private __gap;
|
||||
}
|
||||
|
|
@ -7,22 +7,25 @@ import "@openzeppelin/contracts/utils/Base64.sol";
|
|||
import "@openzeppelin/contracts/utils/Strings.sol";
|
||||
import "./FleekAccessControl.sol";
|
||||
import "./FleekBilling.sol";
|
||||
import "./util/FleekStrings.sol";
|
||||
import "./FleekPausable.sol";
|
||||
import "./FleekAccessPoints.sol";
|
||||
import "./util/FleekStrings.sol";
|
||||
import "./IERCX.sol";
|
||||
|
||||
error AccessPointNotExistent();
|
||||
error AccessPointAlreadyExists();
|
||||
error AccessPointScoreCannotBeLower();
|
||||
error MustBeAccessPointOwner();
|
||||
error MustBeTokenOwner(uint256 tokenId);
|
||||
error ThereIsNoTokenMinted();
|
||||
error InvalidTokenIdForAccessPoint();
|
||||
error AccessPointCreationStatusAlreadySet();
|
||||
|
||||
contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, FleekPausable, FleekBilling {
|
||||
contract FleekERC721 is
|
||||
IERCX,
|
||||
Initializable,
|
||||
ERC721Upgradeable,
|
||||
FleekAccessControl,
|
||||
FleekPausable,
|
||||
FleekBilling,
|
||||
FleekAccessPoints
|
||||
{
|
||||
using Strings for uint256;
|
||||
using FleekStrings for FleekERC721.App;
|
||||
using FleekStrings for FleekERC721.AccessPoint;
|
||||
using FleekStrings for FleekERC721.Token;
|
||||
using FleekStrings for string;
|
||||
using FleekStrings for uint24;
|
||||
|
||||
|
|
@ -36,89 +39,12 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
string gitRepository,
|
||||
string logo,
|
||||
uint24 color,
|
||||
bool accessPointAutoApproval,
|
||||
address indexed minter,
|
||||
address indexed owner
|
||||
);
|
||||
event MetadataUpdate(uint256 indexed _tokenId, string key, string value, address indexed triggeredBy);
|
||||
event MetadataUpdate(uint256 indexed _tokenId, string key, uint24 value, address indexed triggeredBy);
|
||||
event MetadataUpdate(uint256 indexed _tokenId, string key, string[2] value, address indexed triggeredBy);
|
||||
event MetadataUpdate(uint256 indexed _tokenId, string key, bool value, address indexed triggeredBy);
|
||||
|
||||
event NewAccessPoint(string apName, uint256 indexed tokenId, address indexed owner);
|
||||
event RemoveAccessPoint(string apName, uint256 indexed tokenId, address indexed owner);
|
||||
|
||||
event ChangeAccessPointScore(string apName, uint256 indexed tokenId, uint256 score, address indexed triggeredBy);
|
||||
|
||||
event ChangeAccessPointNameVerify(
|
||||
string apName,
|
||||
uint256 tokenId,
|
||||
bool indexed verified,
|
||||
address indexed triggeredBy
|
||||
);
|
||||
event ChangeAccessPointContentVerify(
|
||||
string apName,
|
||||
uint256 tokenId,
|
||||
bool indexed verified,
|
||||
address indexed triggeredBy
|
||||
);
|
||||
event ChangeAccessPointCreationStatus(
|
||||
string apName,
|
||||
uint256 tokenId,
|
||||
AccessPointCreationStatus status,
|
||||
address indexed triggeredBy
|
||||
);
|
||||
|
||||
/**
|
||||
* The properties are stored as string to keep consistency with
|
||||
* other token contracts, we might consider changing for bytes32
|
||||
* in the future due to gas optimization.
|
||||
*/
|
||||
struct App {
|
||||
string name; // Name of the site
|
||||
string description; // Description about the site
|
||||
string externalURL; // Site URL
|
||||
string ENS; // ENS ID
|
||||
uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)
|
||||
mapping(uint256 => Build) builds; // Mapping to build details for each build number
|
||||
string logo;
|
||||
uint24 color; // Color of the nft
|
||||
bool accessPointAutoApproval; // AP Auto Approval
|
||||
}
|
||||
|
||||
/**
|
||||
* The metadata that is stored for each build.
|
||||
*/
|
||||
struct Build {
|
||||
string commitHash;
|
||||
string gitRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creation status enums for access points
|
||||
*/
|
||||
enum AccessPointCreationStatus {
|
||||
DRAFT,
|
||||
APPROVED,
|
||||
REJECTED,
|
||||
REMOVED
|
||||
}
|
||||
|
||||
/**
|
||||
* The stored data for each AccessPoint.
|
||||
*/
|
||||
struct AccessPoint {
|
||||
uint256 tokenId;
|
||||
uint256 score;
|
||||
bool contentVerified;
|
||||
bool nameVerified;
|
||||
address owner;
|
||||
AccessPointCreationStatus status;
|
||||
}
|
||||
|
||||
uint256 private _appIds;
|
||||
mapping(uint256 => App) private _apps;
|
||||
mapping(string => AccessPoint) private _accessPoints;
|
||||
mapping(uint256 => Token) private _apps;
|
||||
|
||||
/**
|
||||
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
|
||||
|
|
@ -134,14 +60,6 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
__FleekPausable_init();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks if the AccessPoint exists.
|
||||
*/
|
||||
modifier requireAP(string memory apName) {
|
||||
if (_accessPoints[apName].owner == address(0)) revert AccessPointNotExistent();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Mints a token and returns a tokenId.
|
||||
*
|
||||
|
|
@ -163,22 +81,20 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
string memory commitHash,
|
||||
string memory gitRepository,
|
||||
string memory logo,
|
||||
uint24 color,
|
||||
bool accessPointAutoApproval
|
||||
uint24 color
|
||||
) public payable requirePayment(Billing.Mint) returns (uint256) {
|
||||
uint256 tokenId = _appIds;
|
||||
_mint(to, tokenId);
|
||||
|
||||
_appIds += 1;
|
||||
|
||||
App storage app = _apps[tokenId];
|
||||
Token storage app = _apps[tokenId];
|
||||
app.name = name;
|
||||
app.description = description;
|
||||
app.externalURL = externalURL;
|
||||
app.ENS = ENS;
|
||||
app.logo = logo;
|
||||
app.color = color;
|
||||
app.accessPointAutoApproval = accessPointAutoApproval;
|
||||
|
||||
// The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.
|
||||
app.currentBuild = 0;
|
||||
|
|
@ -193,7 +109,6 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
gitRepository,
|
||||
logo,
|
||||
color,
|
||||
accessPointAutoApproval,
|
||||
msg.sender,
|
||||
to
|
||||
);
|
||||
|
|
@ -210,12 +125,13 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
* - the tokenId must be minted and valid.
|
||||
*
|
||||
*/
|
||||
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
|
||||
function tokenURI(uint256 tokenId) public view virtual override(ERC721Upgradeable, IERCX) returns (string memory) {
|
||||
_requireMinted(tokenId);
|
||||
address owner = ownerOf(tokenId);
|
||||
App storage app = _apps[tokenId];
|
||||
bool accessPointAutoApproval = _getAccessPointAutoApproval(tokenId);
|
||||
Token storage app = _apps[tokenId];
|
||||
|
||||
return string(abi.encodePacked(_baseURI(), app.toString(owner).toBase64()));
|
||||
return string(abi.encodePacked(_baseURI(), app.toString(owner, accessPointAutoApproval).toBase64()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -237,7 +153,7 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
returns (string memory, string memory, string memory, string memory, uint256, string memory, uint24)
|
||||
{
|
||||
_requireMinted(tokenId);
|
||||
App storage app = _apps[tokenId];
|
||||
Token storage app = _apps[tokenId];
|
||||
return (app.name, app.description, app.externalURL, app.ENS, app.currentBuild, app.logo, app.color);
|
||||
}
|
||||
|
||||
|
|
@ -287,26 +203,6 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
return "data:application/json;base64,";
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates the `accessPointAutoApproval` settings on minted `tokenId`.
|
||||
*
|
||||
* May emit a {MetadataUpdate} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the tokenId must be minted and valid.
|
||||
* - the sender must have the `tokenController` role.
|
||||
*
|
||||
*/
|
||||
function setAccessPointAutoApproval(
|
||||
uint256 tokenId,
|
||||
bool _apAutoApproval
|
||||
) public virtual requireTokenOwner(tokenId) {
|
||||
_requireMinted(tokenId);
|
||||
_apps[tokenId].accessPointAutoApproval = _apAutoApproval;
|
||||
emit MetadataUpdate(tokenId, "accessPointAutoApproval", _apAutoApproval, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates the `externalURL` metadata field of a minted `tokenId`.
|
||||
*
|
||||
|
|
@ -443,197 +339,6 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
setTokenColor(tokenId, _tokenColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Add a new AccessPoint register for an app token.
|
||||
* The AP name should be a DNS or ENS url and it should be unique.
|
||||
* Anyone can add an AP but it should requires a payment.
|
||||
*
|
||||
* May emit a {NewAccessPoint} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the tokenId must be minted and valid.
|
||||
* - billing for add acess point may be applied.
|
||||
* - the contract must be not paused.
|
||||
*
|
||||
*/
|
||||
function addAccessPoint(
|
||||
uint256 tokenId,
|
||||
string memory apName
|
||||
) public payable whenNotPaused requirePayment(Billing.AddAccessPoint) {
|
||||
// require(msg.value == 0.1 ether, "You need to pay at least 0.1 ETH"); // TODO: define a minimum price
|
||||
_requireMinted(tokenId);
|
||||
if (_accessPoints[apName].owner != address(0)) revert AccessPointAlreadyExists();
|
||||
|
||||
emit NewAccessPoint(apName, tokenId, msg.sender);
|
||||
|
||||
if (_apps[tokenId].accessPointAutoApproval) {
|
||||
// Auto Approval is on.
|
||||
_accessPoints[apName] = AccessPoint(
|
||||
tokenId,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
msg.sender,
|
||||
AccessPointCreationStatus.APPROVED
|
||||
);
|
||||
|
||||
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.APPROVED, msg.sender);
|
||||
} else {
|
||||
// Auto Approval is off. Should wait for approval.
|
||||
_accessPoints[apName] = AccessPoint(tokenId, 0, false, false, msg.sender, AccessPointCreationStatus.DRAFT);
|
||||
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.DRAFT, msg.sender);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set approval settings for an access point.
|
||||
* It will add the access point to the token's AP list, if `approved` is true.
|
||||
*
|
||||
* May emit a {ChangeAccessPointApprovalStatus} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the tokenId must exist and be the same as the tokenId that is set for the AP.
|
||||
* - the AP must exist.
|
||||
* - must be called by a token controller.
|
||||
*/
|
||||
function setApprovalForAccessPoint(
|
||||
uint256 tokenId,
|
||||
string memory apName,
|
||||
bool approved
|
||||
) public requireTokenOwner(tokenId) {
|
||||
AccessPoint storage accessPoint = _accessPoints[apName];
|
||||
if (accessPoint.tokenId != tokenId) revert InvalidTokenIdForAccessPoint();
|
||||
if (accessPoint.status != AccessPointCreationStatus.DRAFT) revert AccessPointCreationStatusAlreadySet();
|
||||
|
||||
if (approved) {
|
||||
// Approval
|
||||
accessPoint.status = AccessPointCreationStatus.APPROVED;
|
||||
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.APPROVED, msg.sender);
|
||||
} else {
|
||||
// Not Approved
|
||||
accessPoint.status = AccessPointCreationStatus.REJECTED;
|
||||
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.REJECTED, msg.sender);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Remove an AccessPoint registry for an app token.
|
||||
* It will also remove the AP from the app token APs list.
|
||||
*
|
||||
* May emit a {RemoveAccessPoint} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the AP must exist.
|
||||
* - must be called by the AP owner.
|
||||
* - the contract must be not paused.
|
||||
*
|
||||
*/
|
||||
function removeAccessPoint(string memory apName) public whenNotPaused requireAP(apName) {
|
||||
if (msg.sender != _accessPoints[apName].owner) revert MustBeAccessPointOwner();
|
||||
_accessPoints[apName].status = AccessPointCreationStatus.REMOVED;
|
||||
uint256 tokenId = _accessPoints[apName].tokenId;
|
||||
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.REMOVED, msg.sender);
|
||||
emit RemoveAccessPoint(apName, tokenId, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev A view function to gether information about an AccessPoint.
|
||||
* It returns a JSON string representing the AccessPoint information.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the AP must exist.
|
||||
*
|
||||
*/
|
||||
function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {
|
||||
AccessPoint storage _ap = _accessPoints[apName];
|
||||
return _ap.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev A view function to check if a AccessPoint is verified.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the AP must exist.
|
||||
*
|
||||
*/
|
||||
function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {
|
||||
return _accessPoints[apName].nameVerified;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Increases the score of a AccessPoint registry.
|
||||
*
|
||||
* May emit a {ChangeAccessPointScore} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the AP must exist.
|
||||
*
|
||||
*/
|
||||
function increaseAccessPointScore(string memory apName) public requireAP(apName) {
|
||||
_accessPoints[apName].score++;
|
||||
emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Decreases the score of a AccessPoint registry if is greater than 0.
|
||||
*
|
||||
* May emit a {ChangeAccessPointScore} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the AP must exist.
|
||||
*
|
||||
*/
|
||||
function decreaseAccessPointScore(string memory apName) public requireAP(apName) {
|
||||
if (_accessPoints[apName].score == 0) revert AccessPointScoreCannotBeLower();
|
||||
_accessPoints[apName].score--;
|
||||
emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set the content verification of a AccessPoint registry.
|
||||
*
|
||||
* May emit a {ChangeAccessPointContentVerify} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the AP must exist.
|
||||
* - the sender must have collection verifier role.
|
||||
*
|
||||
*/
|
||||
function setAccessPointContentVerify(
|
||||
string memory apName,
|
||||
bool verified
|
||||
) public requireAP(apName) requireCollectionRole(CollectionRoles.Verifier) {
|
||||
_accessPoints[apName].contentVerified = verified;
|
||||
emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set the name verification of a AccessPoint registry.
|
||||
*
|
||||
* May emit a {ChangeAccessPointNameVerify} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the AP must exist.
|
||||
* - the sender must have collection verifier role.
|
||||
*
|
||||
*/
|
||||
function setAccessPointNameVerify(
|
||||
string memory apName,
|
||||
bool verified
|
||||
) public requireAP(apName) requireCollectionRole(CollectionRoles.Verifier) {
|
||||
_accessPoints[apName].nameVerified = verified;
|
||||
emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Adds a new build to a minted `tokenId`'s builds mapping.
|
||||
*
|
||||
|
|
@ -675,6 +380,142 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
}
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
ACCESS POINTS
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
/**
|
||||
* @dev Mints with access auto approval setting
|
||||
*/
|
||||
function mint(
|
||||
address to,
|
||||
string memory name,
|
||||
string memory description,
|
||||
string memory externalURL,
|
||||
string memory ENS,
|
||||
string memory commitHash,
|
||||
string memory gitRepository,
|
||||
string memory logo,
|
||||
uint24 color,
|
||||
bool accessPointAutoApproval
|
||||
) public payable returns (uint256) {
|
||||
uint256 tokenId = mint(to, name, description, externalURL, ENS, commitHash, gitRepository, logo, color);
|
||||
_setAccessPointAutoApproval(tokenId, accessPointAutoApproval);
|
||||
return tokenId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Add a new AccessPoint register for an app token.
|
||||
* The AP name should be a DNS or ENS url and it should be unique.
|
||||
* Anyone can add an AP but it should requires a payment.
|
||||
*
|
||||
* May emit a {NewAccessPoint} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the tokenId must be minted and valid.
|
||||
* - billing for add acess point may be applied.
|
||||
* - the contract must be not paused.
|
||||
*
|
||||
*/
|
||||
function addAccessPoint(
|
||||
uint256 tokenId,
|
||||
string memory apName
|
||||
) public payable whenNotPaused requirePayment(Billing.AddAccessPoint) {
|
||||
_requireMinted(tokenId);
|
||||
_addAccessPoint(tokenId, apName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Remove an AccessPoint registry for an app token.
|
||||
* It will also remove the AP from the app token APs list.
|
||||
*
|
||||
* May emit a {RemoveAccessPoint} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the AP must exist.
|
||||
* - must be called by the AP owner.
|
||||
* - the contract must be not paused.
|
||||
*
|
||||
*/
|
||||
function removeAccessPoint(string memory apName) public whenNotPaused {
|
||||
_removeAccessPoint(apName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates the `accessPointAutoApproval` settings on minted `tokenId`.
|
||||
*
|
||||
* May emit a {MetadataUpdate} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the tokenId must be minted and valid.
|
||||
* - the sender must have the `tokenController` role.
|
||||
*
|
||||
*/
|
||||
function setAccessPointAutoApproval(uint256 tokenId, bool _apAutoApproval) public requireTokenOwner(tokenId) {
|
||||
_requireMinted(tokenId);
|
||||
_setAccessPointAutoApproval(tokenId, _apAutoApproval);
|
||||
emit MetadataUpdate(tokenId, "accessPointAutoApproval", _apAutoApproval, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set approval settings for an access point.
|
||||
* It will add the access point to the token's AP list, if `approved` is true.
|
||||
*
|
||||
* May emit a {ChangeAccessPointApprovalStatus} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the tokenId must exist and be the same as the tokenId that is set for the AP.
|
||||
* - the AP must exist.
|
||||
* - must be called by a token controller.
|
||||
*/
|
||||
function setApprovalForAccessPoint(
|
||||
uint256 tokenId,
|
||||
string memory apName,
|
||||
bool approved
|
||||
) public requireTokenOwner(tokenId) {
|
||||
_setApprovalForAccessPoint(tokenId, apName, approved);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set the content verification of a AccessPoint registry.
|
||||
*
|
||||
* May emit a {ChangeAccessPointContentVerify} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the AP must exist.
|
||||
* - the sender must have the token controller role.
|
||||
*
|
||||
*/
|
||||
function setAccessPointContentVerify(
|
||||
string memory apName,
|
||||
bool verified
|
||||
) public requireCollectionRole(CollectionRoles.Verifier) {
|
||||
_setAccessPointContentVerify(apName, verified);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set the name verification of a AccessPoint registry.
|
||||
*
|
||||
* May emit a {ChangeAccessPointNameVerify} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the AP must exist.
|
||||
* - the sender must have the token controller role.
|
||||
*
|
||||
*/
|
||||
function setAccessPointNameVerify(
|
||||
string memory apName,
|
||||
bool verified
|
||||
) public requireCollectionRole(CollectionRoles.Verifier) {
|
||||
_setAccessPointNameVerify(apName, verified);
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
ACCESS CONTROL
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.7;
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
|
||||
|
||||
/**
|
||||
* @title ERCX Interface
|
||||
* @author
|
||||
* @notice
|
||||
*
|
||||
* ERCX is a standard for NFTs that represent websites. It is a standard that
|
||||
* allows for the storage of metadata about a website, and allows for the
|
||||
* storage of multiple builds of a website. This allows for the NFT to be
|
||||
* used as a way to store the history of a website.
|
||||
*/
|
||||
interface IERCX {
|
||||
/**
|
||||
* Event emitted when a token's metadata is updated.
|
||||
* @param _tokenId the updated token id.
|
||||
* @param key which metadata key was updated
|
||||
* @param value the new value of the metadata
|
||||
* @param triggeredBy the address that triggered the update
|
||||
*/
|
||||
event MetadataUpdate(uint256 indexed _tokenId, string key, string value, address indexed triggeredBy);
|
||||
event MetadataUpdate(uint256 indexed _tokenId, string key, uint24 value, address indexed triggeredBy);
|
||||
event MetadataUpdate(uint256 indexed _tokenId, string key, string[2] value, address indexed triggeredBy);
|
||||
event MetadataUpdate(uint256 indexed _tokenId, string key, bool value, address indexed triggeredBy);
|
||||
|
||||
/**
|
||||
* The metadata that is stored for each build.
|
||||
*/
|
||||
struct Build {
|
||||
string commitHash;
|
||||
string gitRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* The properties are stored as string to keep consistency with
|
||||
* other token contracts, we might consider changing for bytes32
|
||||
* in the future due to gas optimization.
|
||||
*/
|
||||
struct Token {
|
||||
string name; // Name of the site
|
||||
string description; // Description about the site
|
||||
string externalURL; // Site URL
|
||||
string ENS; // ENS for the site
|
||||
string logo; // Branding logo
|
||||
uint24 color; // Branding color
|
||||
uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)
|
||||
mapping(uint256 => Build) builds; // Mapping to build details for each build number
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Mints a token and returns a tokenId.
|
||||
*/
|
||||
function mint(
|
||||
address to,
|
||||
string memory name,
|
||||
string memory description,
|
||||
string memory externalURL,
|
||||
string memory ENS,
|
||||
string memory commitHash,
|
||||
string memory gitRepository,
|
||||
string memory logo,
|
||||
uint24 color
|
||||
) external payable returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Sets a minted token's external URL.
|
||||
*/
|
||||
function setTokenExternalURL(uint256 tokenId, string memory _tokenExternalURL) external;
|
||||
|
||||
/**
|
||||
* @dev Sets a minted token's ENS.
|
||||
*/
|
||||
function setTokenENS(uint256 tokenId, string memory _tokenENS) external;
|
||||
|
||||
/**
|
||||
* @dev Sets a minted token's name.
|
||||
*/
|
||||
function setTokenName(uint256 tokenId, string memory _tokenName) external;
|
||||
|
||||
/**
|
||||
* @dev Sets a minted token's description.
|
||||
*/
|
||||
function setTokenDescription(uint256 tokenId, string memory _tokenDescription) external;
|
||||
|
||||
/**
|
||||
* @dev Sets a minted token's logo.
|
||||
*/
|
||||
function setTokenLogo(uint256 tokenId, string memory _tokenLogo) external;
|
||||
|
||||
/**
|
||||
* @dev Sets a minted token's color.
|
||||
*/
|
||||
function setTokenColor(uint256 tokenId, uint24 _tokenColor) external;
|
||||
|
||||
/**
|
||||
* @dev Sets a minted token's build.
|
||||
*/
|
||||
function setTokenBuild(uint256 tokenId, string memory commitHash, string memory gitRepository) external;
|
||||
|
||||
/**
|
||||
* @dev Returns the token metadata for a given tokenId.
|
||||
* It must return a valid JSON object in string format encoded in Base64.
|
||||
*/
|
||||
function tokenURI(uint256 tokenId) external returns (string memory);
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
pragma solidity ^0.8.7;
|
||||
|
||||
import "../FleekERC721.sol";
|
||||
import "@openzeppelin/contracts/utils/Strings.sol";
|
||||
import "@openzeppelin/contracts/utils/Base64.sol";
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
pragma solidity ^0.8.7;
|
||||
|
||||
import "../FleekERC721.sol";
|
||||
import "@openzeppelin/contracts/utils/Strings.sol";
|
||||
import "@openzeppelin/contracts/utils/Base64.sol";
|
||||
import "./FleekSVG.sol";
|
||||
import "../IERCX.sol";
|
||||
import "../FleekAccessPoints.sol";
|
||||
|
||||
library FleekStrings {
|
||||
using Strings for uint256;
|
||||
|
|
@ -29,10 +30,14 @@ library FleekStrings {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev Converts FleekERC721.App to a JSON string.
|
||||
* @dev Converts IERCX.Token to a JSON string.
|
||||
* It requires to receive owner address as a parameter.
|
||||
*/
|
||||
function toString(FleekERC721.App storage app, address owner) internal view returns (string memory) {
|
||||
function toString(
|
||||
IERCX.Token storage app,
|
||||
address owner,
|
||||
bool accessPointAutoApproval
|
||||
) internal view returns (string memory) {
|
||||
// prettier-ignore
|
||||
return string(abi.encodePacked(
|
||||
'{',
|
||||
|
|
@ -41,7 +46,7 @@ library FleekStrings {
|
|||
'"owner":"', uint160(owner).toHexString(20), '",',
|
||||
'"external_url":"', app.externalURL, '",',
|
||||
'"image":"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '",',
|
||||
'"access_point_auto_approval":',app.accessPointAutoApproval.toString(),',',
|
||||
'"access_point_auto_approval":', accessPointAutoApproval.toString(),',',
|
||||
'"attributes": [',
|
||||
'{"trait_type": "ENS", "value":"', app.ENS,'"},',
|
||||
'{"trait_type": "Commit Hash", "value":"', app.builds[app.currentBuild].commitHash,'"},',
|
||||
|
|
@ -54,9 +59,9 @@ library FleekStrings {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev Converts FleekERC721.AccessPoint to a JSON string.
|
||||
* @dev Converts FleekAccessPoints.AccessPoint to a JSON string.
|
||||
*/
|
||||
function toString(FleekERC721.AccessPoint storage ap) internal view returns (string memory) {
|
||||
function toString(FleekAccessPoints.AccessPoint storage ap) internal view returns (string memory) {
|
||||
// prettier-ignore
|
||||
return string(abi.encodePacked(
|
||||
"{",
|
||||
|
|
|
|||
|
|
@ -91,7 +91,9 @@ const mintTo = '0x7ED735b7095C05d78dF169F991f2b7f1A1F1A049';
|
|||
console.log('SVG length: ', params[params.length - 1].length);
|
||||
params.push(await getSVGColor(svgPath));
|
||||
|
||||
const transaction = await contract.mint(...params);
|
||||
const transaction = await contract[
|
||||
'mint(address,string,string,string,string,string,string,string,uint24)'
|
||||
](...params);
|
||||
|
||||
console.log('Response: ', transaction);
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
||||
import { ethers } from 'hardhat';
|
||||
import { expect } from 'chai';
|
||||
import { Fixtures, TestConstants, Errors } from './helpers';
|
||||
import {
|
||||
Fixtures,
|
||||
TestConstants,
|
||||
Errors,
|
||||
OverloadedFunctions,
|
||||
} from './helpers';
|
||||
|
||||
const { Billing, MintParams } = TestConstants;
|
||||
|
||||
|
|
@ -12,7 +17,7 @@ describe('FleekERC721.Billing', () => {
|
|||
|
||||
const mint = (value?: any) => {
|
||||
const { contract, owner } = fixture;
|
||||
return contract.mint(
|
||||
return contract[OverloadedFunctions.Mint.Default](
|
||||
owner.address,
|
||||
MintParams.name,
|
||||
MintParams.description,
|
||||
|
|
@ -22,7 +27,6 @@ describe('FleekERC721.Billing', () => {
|
|||
MintParams.gitRepository,
|
||||
MintParams.logo,
|
||||
MintParams.color,
|
||||
MintParams.accessPointAutoApprovalSettings,
|
||||
{ value }
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
||||
import { expect } from 'chai';
|
||||
import { TestConstants, Fixtures, Errors } from './helpers';
|
||||
import {
|
||||
TestConstants,
|
||||
Fixtures,
|
||||
Errors,
|
||||
OverloadedFunctions,
|
||||
} from './helpers';
|
||||
|
||||
const { CollectionRoles } = TestConstants;
|
||||
|
||||
|
|
@ -179,7 +184,7 @@ describe('FleekERC721.CollectionRoles', () => {
|
|||
it('should not be able to verify access point if not verifier', async () => {
|
||||
const { contract, otherAccount } = fixture;
|
||||
|
||||
await contract.mint(
|
||||
await contract[OverloadedFunctions.Mint.Default](
|
||||
otherAccount.address,
|
||||
TestConstants.MintParams.name,
|
||||
TestConstants.MintParams.description,
|
||||
|
|
@ -188,8 +193,7 @@ describe('FleekERC721.CollectionRoles', () => {
|
|||
TestConstants.MintParams.commitHash,
|
||||
TestConstants.MintParams.gitRepository,
|
||||
TestConstants.MintParams.logo,
|
||||
TestConstants.MintParams.color,
|
||||
TestConstants.MintParams.accessPointAutoApprovalSettings
|
||||
TestConstants.MintParams.color
|
||||
);
|
||||
|
||||
await contract.addAccessPoint(0, 'random.com');
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
||||
import { expect } from 'chai';
|
||||
import { TestConstants, Fixtures, Errors } from './helpers';
|
||||
import { ethers } from 'hardhat';
|
||||
|
||||
const { MintParams, Roles } = TestConstants;
|
||||
import {
|
||||
TestConstants,
|
||||
Fixtures,
|
||||
Errors,
|
||||
OverloadedFunctions,
|
||||
} from './helpers';
|
||||
|
||||
describe('FleekERC721.GetLastTokenId', () => {
|
||||
let fixture: Awaited<ReturnType<typeof Fixtures.default>>;
|
||||
|
||||
const mint = async () => {
|
||||
const response = await fixture.contract.mint(
|
||||
const response = await fixture.contract[OverloadedFunctions.Mint.Default](
|
||||
fixture.owner.address,
|
||||
TestConstants.MintParams.name,
|
||||
TestConstants.MintParams.description,
|
||||
|
|
@ -18,8 +20,7 @@ describe('FleekERC721.GetLastTokenId', () => {
|
|||
TestConstants.MintParams.commitHash,
|
||||
TestConstants.MintParams.gitRepository,
|
||||
TestConstants.MintParams.logo,
|
||||
TestConstants.MintParams.color,
|
||||
false
|
||||
TestConstants.MintParams.color
|
||||
);
|
||||
|
||||
return response;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { ethers, upgrades } from 'hardhat';
|
||||
import { TestConstants } from './constants';
|
||||
import { OverloadedFunctions } from './overloaded-functions';
|
||||
|
||||
export abstract class Fixtures {
|
||||
static async paused() {}
|
||||
|
|
@ -35,7 +36,9 @@ export abstract class Fixtures {
|
|||
static async withMint() {
|
||||
const fromDefault = await Fixtures.default();
|
||||
|
||||
const response = await fromDefault.contract.mint(
|
||||
const response = await fromDefault.contract[
|
||||
OverloadedFunctions.Mint.Default
|
||||
](
|
||||
fromDefault.owner.address,
|
||||
TestConstants.MintParams.name,
|
||||
TestConstants.MintParams.description,
|
||||
|
|
@ -44,8 +47,7 @@ export abstract class Fixtures {
|
|||
TestConstants.MintParams.commitHash,
|
||||
TestConstants.MintParams.gitRepository,
|
||||
TestConstants.MintParams.logo,
|
||||
TestConstants.MintParams.color,
|
||||
TestConstants.MintParams.accessPointAutoApprovalSettings
|
||||
TestConstants.MintParams.color
|
||||
);
|
||||
|
||||
const tokenId = response.value.toNumber();
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@ export * from './fixture';
|
|||
export * from './utils';
|
||||
export * from './errors';
|
||||
export * from './events';
|
||||
export * from './overloaded-functions';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
export const OverloadedFunctions = Object.freeze({
|
||||
Mint: {
|
||||
Default:
|
||||
'mint(address,string,string,string,string,string,string,string,uint24)',
|
||||
WithAPAutoApproval:
|
||||
'mint(address,string,string,string,string,string,string,string,uint24,bool)',
|
||||
},
|
||||
});
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
||||
import { expect } from 'chai';
|
||||
import { TestConstants, Fixtures, Errors } from './helpers';
|
||||
import { TestConstants, Fixtures, OverloadedFunctions } from './helpers';
|
||||
import { ethers } from 'hardhat';
|
||||
|
||||
const { MintParams, CollectionRoles } = TestConstants;
|
||||
const { MintParams } = TestConstants;
|
||||
|
||||
describe('FleekERC721.Minting', () => {
|
||||
it('should be able to mint a new token', async () => {
|
||||
const { owner, contract } = await loadFixture(Fixtures.default);
|
||||
|
||||
const response = await contract.mint(
|
||||
const response = await contract[OverloadedFunctions.Mint.Default](
|
||||
owner.address,
|
||||
MintParams.name,
|
||||
MintParams.description,
|
||||
|
|
@ -18,8 +18,7 @@ describe('FleekERC721.Minting', () => {
|
|||
MintParams.commitHash,
|
||||
MintParams.gitRepository,
|
||||
MintParams.logo,
|
||||
MintParams.color,
|
||||
MintParams.accessPointAutoApprovalSettings
|
||||
MintParams.color
|
||||
);
|
||||
|
||||
expect(response.value).to.be.instanceOf(ethers.BigNumber);
|
||||
|
|
@ -31,7 +30,7 @@ describe('FleekERC721.Minting', () => {
|
|||
Fixtures.default
|
||||
);
|
||||
|
||||
const response = await contract.mint(
|
||||
const response = await contract[OverloadedFunctions.Mint.Default](
|
||||
owner.address,
|
||||
MintParams.name,
|
||||
MintParams.description,
|
||||
|
|
@ -40,8 +39,7 @@ describe('FleekERC721.Minting', () => {
|
|||
MintParams.commitHash,
|
||||
MintParams.gitRepository,
|
||||
MintParams.logo,
|
||||
MintParams.color,
|
||||
MintParams.accessPointAutoApprovalSettings
|
||||
MintParams.color
|
||||
);
|
||||
|
||||
const tokenId = response.value.toNumber();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
||||
import { expect } from 'chai';
|
||||
import { TestConstants, Fixtures, Errors } from './helpers';
|
||||
import {
|
||||
TestConstants,
|
||||
Fixtures,
|
||||
Errors,
|
||||
OverloadedFunctions,
|
||||
} from './helpers';
|
||||
|
||||
const { MintParams, CollectionRoles, TokenRoles } = TestConstants;
|
||||
|
||||
|
|
@ -10,7 +15,7 @@ describe('FleekERC721.Pausable', () => {
|
|||
const mint = () => {
|
||||
const { owner, contract } = fixture;
|
||||
|
||||
return contract.mint(
|
||||
return contract[OverloadedFunctions.Mint.Default](
|
||||
owner.address,
|
||||
MintParams.name,
|
||||
MintParams.description,
|
||||
|
|
@ -19,8 +24,7 @@ describe('FleekERC721.Pausable', () => {
|
|||
MintParams.commitHash,
|
||||
MintParams.gitRepository,
|
||||
MintParams.logo,
|
||||
MintParams.color,
|
||||
false
|
||||
MintParams.color
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import {
|
|||
NewAccessPoint as NewAccessPointEvent,
|
||||
ChangeAccessPointNameVerify as ChangeAccessPointNameVerifyEvent,
|
||||
ChangeAccessPointContentVerify as ChangeAccessPointContentVerifyEvent,
|
||||
TokenRolesCleared as TokenRolesClearedEvent
|
||||
TokenRolesCleared as TokenRolesClearedEvent,
|
||||
} from '../generated/FleekNFA/FleekNFA';
|
||||
|
||||
// Entity Imports [based on the schema]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"version": "0.5.4",
|
||||
"timestamp": 1678390993500
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,13 @@ import {
|
|||
afterAll,
|
||||
} from 'matchstick-as/assembly/index';
|
||||
import { BigInt, Bytes } from '@graphprotocol/graph-ts';
|
||||
import { createNewCollectionRoleChanged, handleCollectionRoleChangedList, makeEventId, USER_ONE, USER_TWO } from '../helpers/utils';
|
||||
import {
|
||||
createNewCollectionRoleChanged,
|
||||
handleCollectionRoleChangedList,
|
||||
makeEventId,
|
||||
USER_ONE,
|
||||
USER_TWO,
|
||||
} from '../helpers/utils';
|
||||
import { CollectionRoleChanged } from '../../../generated/FleekNFA/FleekNFA';
|
||||
|
||||
describe('Collection Role Changed tests', () => {
|
||||
|
|
@ -16,14 +22,13 @@ describe('Collection Role Changed tests', () => {
|
|||
let collectionRoleChangedList: CollectionRoleChanged[] = [];
|
||||
|
||||
collectionRoleChangedList.push(
|
||||
createNewCollectionRoleChanged(0, 0, USER_ONE, true, USER_TWO) // User Two grants collection owner access to User One
|
||||
createNewCollectionRoleChanged(0, 0, USER_ONE, true, USER_TWO) // User Two grants collection owner access to User One
|
||||
);
|
||||
|
||||
collectionRoleChangedList.push(
|
||||
createNewCollectionRoleChanged(2, 0, USER_ONE, false, USER_TWO) // User Two revokes the owner access of User One to the collection
|
||||
);
|
||||
|
||||
|
||||
handleCollectionRoleChangedList(collectionRoleChangedList);
|
||||
});
|
||||
|
||||
|
|
@ -33,18 +38,8 @@ describe('Collection Role Changed tests', () => {
|
|||
|
||||
describe('Assertions', () => {
|
||||
test('Check the `role` field of each CollectionRoleChanged event entity', () => {
|
||||
assert.fieldEquals(
|
||||
'CollectionRoleChanged',
|
||||
makeEventId(0),
|
||||
'role',
|
||||
'0'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'CollectionRoleChanged',
|
||||
makeEventId(2),
|
||||
'role',
|
||||
'0'
|
||||
);
|
||||
assert.fieldEquals('CollectionRoleChanged', makeEventId(0), 'role', '0');
|
||||
assert.fieldEquals('CollectionRoleChanged', makeEventId(2), 'role', '0');
|
||||
});
|
||||
|
||||
test('Check the `toAddress` field of each CollectionRoleChanged event entity', () => {
|
||||
|
|
@ -78,18 +73,8 @@ describe('Collection Role Changed tests', () => {
|
|||
});
|
||||
|
||||
test('Check the `status` field of each CollectionRoleChanged event entity', () => {
|
||||
assert.fieldEquals(
|
||||
'TokenRoleChanged',
|
||||
makeEventId(0),
|
||||
'status',
|
||||
'true'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'TokenRoleChanged',
|
||||
makeEventId(2),
|
||||
'status',
|
||||
'false'
|
||||
);
|
||||
assert.fieldEquals('TokenRoleChanged', makeEventId(0), 'status', 'true');
|
||||
assert.fieldEquals('TokenRoleChanged', makeEventId(2), 'status', 'false');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,7 +7,13 @@ import {
|
|||
afterAll,
|
||||
} from 'matchstick-as/assembly/index';
|
||||
import { BigInt, Bytes } from '@graphprotocol/graph-ts';
|
||||
import { createNewTokenRoleChanged, handleTokenRoleChangedList, makeEventId, USER_ONE, USER_TWO } from '../helpers/utils';
|
||||
import {
|
||||
createNewTokenRoleChanged,
|
||||
handleTokenRoleChangedList,
|
||||
makeEventId,
|
||||
USER_ONE,
|
||||
USER_TWO,
|
||||
} from '../helpers/utils';
|
||||
import { TokenRoleChanged } from '../../../generated/FleekNFA/FleekNFA';
|
||||
|
||||
describe('Token Role Changed tests', () => {
|
||||
|
|
@ -16,18 +22,38 @@ describe('Token Role Changed tests', () => {
|
|||
let tokenRoleChangedList: TokenRoleChanged[] = [];
|
||||
|
||||
tokenRoleChangedList.push(
|
||||
createNewTokenRoleChanged(0, BigInt.fromI32(0), 0, USER_ONE, true, USER_TWO) // User Two gives User One controller access to TokenId 0
|
||||
createNewTokenRoleChanged(
|
||||
0,
|
||||
BigInt.fromI32(0),
|
||||
0,
|
||||
USER_ONE,
|
||||
true,
|
||||
USER_TWO
|
||||
) // User Two gives User One controller access to TokenId 0
|
||||
);
|
||||
|
||||
tokenRoleChangedList.push(
|
||||
createNewTokenRoleChanged(1, BigInt.fromI32(1), 0, USER_TWO, true, USER_ONE) // User One gives User Two controller access to TokenId 1
|
||||
createNewTokenRoleChanged(
|
||||
1,
|
||||
BigInt.fromI32(1),
|
||||
0,
|
||||
USER_TWO,
|
||||
true,
|
||||
USER_ONE
|
||||
) // User One gives User Two controller access to TokenId 1
|
||||
);
|
||||
|
||||
tokenRoleChangedList.push(
|
||||
createNewTokenRoleChanged(2, BigInt.fromI32(0), 0, USER_ONE, false, USER_TWO) // User Two revokes the controller access of User One to tokenId 0
|
||||
createNewTokenRoleChanged(
|
||||
2,
|
||||
BigInt.fromI32(0),
|
||||
0,
|
||||
USER_ONE,
|
||||
false,
|
||||
USER_TWO
|
||||
) // User Two revokes the controller access of User One to tokenId 0
|
||||
);
|
||||
|
||||
|
||||
handleTokenRoleChangedList(tokenRoleChangedList);
|
||||
});
|
||||
|
||||
|
|
@ -37,44 +63,14 @@ describe('Token Role Changed tests', () => {
|
|||
|
||||
describe('Assertions', () => {
|
||||
test('Check the `tokenId` field of each TokenRoleChanged event entity', () => {
|
||||
assert.fieldEquals(
|
||||
'TokenRoleChanged',
|
||||
makeEventId(0),
|
||||
'tokenId',
|
||||
'0'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'TokenRoleChanged',
|
||||
makeEventId(1),
|
||||
'tokenId',
|
||||
'1'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'TokenRoleChanged',
|
||||
makeEventId(2),
|
||||
'tokenId',
|
||||
'0'
|
||||
);
|
||||
assert.fieldEquals('TokenRoleChanged', makeEventId(0), 'tokenId', '0');
|
||||
assert.fieldEquals('TokenRoleChanged', makeEventId(1), 'tokenId', '1');
|
||||
assert.fieldEquals('TokenRoleChanged', makeEventId(2), 'tokenId', '0');
|
||||
});
|
||||
test('Check the `role` field of each TokenRoleChanged event entity', () => {
|
||||
assert.fieldEquals(
|
||||
'TokenRoleChanged',
|
||||
makeEventId(0),
|
||||
'role',
|
||||
'0'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'TokenRoleChanged',
|
||||
makeEventId(1),
|
||||
'role',
|
||||
'0'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'TokenRoleChanged',
|
||||
makeEventId(2),
|
||||
'role',
|
||||
'0'
|
||||
);
|
||||
assert.fieldEquals('TokenRoleChanged', makeEventId(0), 'role', '0');
|
||||
assert.fieldEquals('TokenRoleChanged', makeEventId(1), 'role', '0');
|
||||
assert.fieldEquals('TokenRoleChanged', makeEventId(2), 'role', '0');
|
||||
});
|
||||
|
||||
test('Check the `toAddress` field of each TokenRoleChanged event entity', () => {
|
||||
|
|
@ -120,24 +116,9 @@ describe('Token Role Changed tests', () => {
|
|||
});
|
||||
|
||||
test('Check the `status` field of each TokenRoleChanged event entity', () => {
|
||||
assert.fieldEquals(
|
||||
'TokenRoleChanged',
|
||||
makeEventId(0),
|
||||
'status',
|
||||
'true'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'TokenRoleChanged',
|
||||
makeEventId(1),
|
||||
'status',
|
||||
'true'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'TokenRoleChanged',
|
||||
makeEventId(2),
|
||||
'status',
|
||||
'false'
|
||||
);
|
||||
assert.fieldEquals('TokenRoleChanged', makeEventId(0), 'status', 'true');
|
||||
assert.fieldEquals('TokenRoleChanged', makeEventId(1), 'status', 'true');
|
||||
assert.fieldEquals('TokenRoleChanged', makeEventId(2), 'status', 'false');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,98 +1,115 @@
|
|||
import {
|
||||
assert,
|
||||
describe,
|
||||
test,
|
||||
clearStore,
|
||||
beforeAll,
|
||||
afterAll,
|
||||
} from 'matchstick-as/assembly/index';
|
||||
import { BigInt, Bytes } from '@graphprotocol/graph-ts';
|
||||
import { createNewAccessPointEvent, createNewChangeAccessPointCreationStatus, handleChangeAccessPointCreationStatusList, handleNewAccessPoints, makeEventId, USER_ONE, USER_TWO } from '../helpers/utils';
|
||||
import { ChangeAccessPointCreationStatus, NewAccessPoint } from '../../../generated/FleekNFA/FleekNFA';
|
||||
assert,
|
||||
describe,
|
||||
test,
|
||||
clearStore,
|
||||
beforeAll,
|
||||
afterAll,
|
||||
} from 'matchstick-as/assembly/index';
|
||||
import { BigInt, Bytes } from '@graphprotocol/graph-ts';
|
||||
import {
|
||||
createNewAccessPointEvent,
|
||||
createNewChangeAccessPointCreationStatus,
|
||||
handleChangeAccessPointCreationStatusList,
|
||||
handleNewAccessPoints,
|
||||
makeEventId,
|
||||
USER_ONE,
|
||||
USER_TWO,
|
||||
} from '../helpers/utils';
|
||||
import {
|
||||
ChangeAccessPointCreationStatus,
|
||||
NewAccessPoint,
|
||||
} from '../../../generated/FleekNFA/FleekNFA';
|
||||
|
||||
describe('Change Access Point Creation Status tests', () => {
|
||||
beforeAll(() => {
|
||||
beforeAll(() => {
|
||||
// New Access Points
|
||||
let newAccessPoints: NewAccessPoint[] = [];
|
||||
|
||||
// User One has two access points: one for tokenId 0 and one for tokenId 1
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE)
|
||||
);
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE)
|
||||
);
|
||||
|
||||
// User Two has one access point for tokenId 0
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO)
|
||||
);
|
||||
handleNewAccessPoints(newAccessPoints);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
clearStore();
|
||||
});
|
||||
|
||||
describe('Assertions', () => {
|
||||
test('Check the `creationStatus` field of each access point entity', () => {
|
||||
assert.fieldEquals('AccessPoint', 'firstAP', 'creationStatus', 'DRAFT');
|
||||
assert.fieldEquals('AccessPoint', 'secondAP', 'creationStatus', 'DRAFT');
|
||||
assert.fieldEquals('AccessPoint', 'thirdAP', 'creationStatus', 'DRAFT');
|
||||
});
|
||||
|
||||
test('Check the `creationStatus` field of each access point entity after changing it', () => {
|
||||
// New Access Points
|
||||
let newAccessPoints: NewAccessPoint[] = [];
|
||||
let changeAccessPointCreationStatusList: ChangeAccessPointCreationStatus[] =
|
||||
[];
|
||||
|
||||
// User One has two access points: one for tokenId 0 and one for tokenId 1
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE)
|
||||
changeAccessPointCreationStatusList.push(
|
||||
createNewChangeAccessPointCreationStatus(
|
||||
0,
|
||||
'firstAP',
|
||||
BigInt.fromI32(0),
|
||||
1,
|
||||
USER_ONE
|
||||
)
|
||||
);
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE)
|
||||
changeAccessPointCreationStatusList.push(
|
||||
createNewChangeAccessPointCreationStatus(
|
||||
0,
|
||||
'secondAP',
|
||||
BigInt.fromI32(1),
|
||||
1,
|
||||
USER_ONE
|
||||
)
|
||||
);
|
||||
|
||||
// User Two has one access point for tokenId 0
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO)
|
||||
changeAccessPointCreationStatusList.push(
|
||||
createNewChangeAccessPointCreationStatus(
|
||||
0,
|
||||
'thirdAP',
|
||||
BigInt.fromI32(0),
|
||||
1,
|
||||
USER_TWO
|
||||
)
|
||||
);
|
||||
handleNewAccessPoints(newAccessPoints);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
clearStore();
|
||||
});
|
||||
|
||||
describe('Assertions', () => {
|
||||
test('Check the `creationStatus` field of each access point entity', () => {
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'firstAP',
|
||||
'creationStatus',
|
||||
'DRAFT'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'secondAP',
|
||||
'creationStatus',
|
||||
'DRAFT'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'thirdAP',
|
||||
'creationStatus',
|
||||
'DRAFT'
|
||||
);
|
||||
});
|
||||
|
||||
test('Check the `creationStatus` field of each access point entity after changing it', () => {
|
||||
// New Access Points
|
||||
let changeAccessPointCreationStatusList: ChangeAccessPointCreationStatus[] = [];
|
||||
|
||||
// User One has two access points: one for tokenId 0 and one for tokenId 1
|
||||
changeAccessPointCreationStatusList.push(
|
||||
createNewChangeAccessPointCreationStatus(0, 'firstAP', BigInt.fromI32(0), 1, USER_ONE)
|
||||
);
|
||||
changeAccessPointCreationStatusList.push(
|
||||
createNewChangeAccessPointCreationStatus(0, 'secondAP', BigInt.fromI32(1), 1, USER_ONE)
|
||||
);
|
||||
handleChangeAccessPointCreationStatusList(
|
||||
changeAccessPointCreationStatusList
|
||||
);
|
||||
|
||||
// User Two has one access point for tokenId 0
|
||||
changeAccessPointCreationStatusList.push(
|
||||
createNewChangeAccessPointCreationStatus(0, 'thirdAP', BigInt.fromI32(0), 1, USER_TWO)
|
||||
);
|
||||
|
||||
handleChangeAccessPointCreationStatusList(changeAccessPointCreationStatusList);
|
||||
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'firstAP',
|
||||
'creationStatus',
|
||||
'APPROVED'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'secondAP',
|
||||
'creationStatus',
|
||||
'APPROVED'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'thirdAP',
|
||||
'creationStatus',
|
||||
'APPROVED'
|
||||
);
|
||||
});
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'firstAP',
|
||||
'creationStatus',
|
||||
'APPROVED'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'secondAP',
|
||||
'creationStatus',
|
||||
'APPROVED'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'thirdAP',
|
||||
'creationStatus',
|
||||
'APPROVED'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,96 +1,94 @@
|
|||
import {
|
||||
assert,
|
||||
describe,
|
||||
test,
|
||||
clearStore,
|
||||
beforeAll,
|
||||
afterAll,
|
||||
} from 'matchstick-as/assembly/index';
|
||||
import { BigInt } from '@graphprotocol/graph-ts';
|
||||
import { createNewAccessPointEvent, createNewChangeAccessPointNameVerify, handleChangeAccessPointNameVerifies, handleNewAccessPoints, USER_ONE, USER_TWO } from '../helpers/utils';
|
||||
import { ChangeAccessPointNameVerify, NewAccessPoint } from '../../../generated/FleekNFA/FleekNFA';
|
||||
assert,
|
||||
describe,
|
||||
test,
|
||||
clearStore,
|
||||
beforeAll,
|
||||
afterAll,
|
||||
} from 'matchstick-as/assembly/index';
|
||||
import { BigInt } from '@graphprotocol/graph-ts';
|
||||
import {
|
||||
createNewAccessPointEvent,
|
||||
createNewChangeAccessPointNameVerify,
|
||||
handleChangeAccessPointNameVerifies,
|
||||
handleNewAccessPoints,
|
||||
USER_ONE,
|
||||
USER_TWO,
|
||||
} from '../helpers/utils';
|
||||
import {
|
||||
ChangeAccessPointNameVerify,
|
||||
NewAccessPoint,
|
||||
} from '../../../generated/FleekNFA/FleekNFA';
|
||||
|
||||
describe('Change Access Point Name Verify tests', () => {
|
||||
beforeAll(() => {
|
||||
// New Access Points
|
||||
let newAccessPoints: NewAccessPoint[] = [];
|
||||
beforeAll(() => {
|
||||
// New Access Points
|
||||
let newAccessPoints: NewAccessPoint[] = [];
|
||||
|
||||
// User One has two access points: one for tokenId 0 and one for tokenId 1
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE)
|
||||
// User One has two access points: one for tokenId 0 and one for tokenId 1
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE)
|
||||
);
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE)
|
||||
);
|
||||
|
||||
// User Two has one access point for tokenId 0
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO)
|
||||
);
|
||||
handleNewAccessPoints(newAccessPoints);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
clearStore();
|
||||
});
|
||||
|
||||
describe('Assertions', () => {
|
||||
test('Check the `nameVerified` field of each access point entity', () => {
|
||||
assert.fieldEquals('AccessPoint', 'firstAP', 'nameVerified', 'false');
|
||||
assert.fieldEquals('AccessPoint', 'secondAP', 'nameVerified', 'false');
|
||||
assert.fieldEquals('AccessPoint', 'thirdAP', 'nameVerified', 'false');
|
||||
});
|
||||
|
||||
test('Check the `nameVerified` field of each access point entity after changing it', () => {
|
||||
// New Access Point Name Verified fields
|
||||
let changeAccessPointNameVerifies: ChangeAccessPointNameVerify[] = [];
|
||||
|
||||
changeAccessPointNameVerifies.push(
|
||||
createNewChangeAccessPointNameVerify(
|
||||
0,
|
||||
'firstAP',
|
||||
BigInt.fromI32(0),
|
||||
true,
|
||||
USER_ONE
|
||||
)
|
||||
);
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE)
|
||||
changeAccessPointNameVerifies.push(
|
||||
createNewChangeAccessPointNameVerify(
|
||||
0,
|
||||
'secondAP',
|
||||
BigInt.fromI32(1),
|
||||
true,
|
||||
USER_ONE
|
||||
)
|
||||
);
|
||||
|
||||
// User Two has one access point for tokenId 0
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO)
|
||||
changeAccessPointNameVerifies.push(
|
||||
createNewChangeAccessPointNameVerify(
|
||||
0,
|
||||
'thirdAP',
|
||||
BigInt.fromI32(0),
|
||||
true,
|
||||
USER_TWO
|
||||
)
|
||||
);
|
||||
handleNewAccessPoints(newAccessPoints);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
clearStore();
|
||||
});
|
||||
|
||||
describe('Assertions', () => {
|
||||
test('Check the `nameVerified` field of each access point entity', () => {
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'firstAP',
|
||||
'nameVerified',
|
||||
'false'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'secondAP',
|
||||
'nameVerified',
|
||||
'false'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'thirdAP',
|
||||
'nameVerified',
|
||||
'false'
|
||||
);
|
||||
});
|
||||
|
||||
test('Check the `nameVerified` field of each access point entity after changing it', () => {
|
||||
// New Access Point Name Verified fields
|
||||
let changeAccessPointNameVerifies: ChangeAccessPointNameVerify[] = [];
|
||||
|
||||
changeAccessPointNameVerifies.push(
|
||||
createNewChangeAccessPointNameVerify(0, 'firstAP', BigInt.fromI32(0), true, USER_ONE)
|
||||
);
|
||||
changeAccessPointNameVerifies.push(
|
||||
createNewChangeAccessPointNameVerify(0, 'secondAP', BigInt.fromI32(1), true, USER_ONE)
|
||||
);
|
||||
handleChangeAccessPointNameVerifies(changeAccessPointNameVerifies);
|
||||
|
||||
changeAccessPointNameVerifies.push(
|
||||
createNewChangeAccessPointNameVerify(0, 'thirdAP', BigInt.fromI32(0), true, USER_TWO)
|
||||
);
|
||||
|
||||
handleChangeAccessPointNameVerifies(changeAccessPointNameVerifies);
|
||||
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'firstAP',
|
||||
'nameVerified',
|
||||
'true'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'secondAP',
|
||||
'nameVerified',
|
||||
'true'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'AccessPoint',
|
||||
'thirdAP',
|
||||
'nameVerified',
|
||||
'true'
|
||||
);
|
||||
});
|
||||
assert.fieldEquals('AccessPoint', 'firstAP', 'nameVerified', 'true');
|
||||
assert.fieldEquals('AccessPoint', 'secondAP', 'nameVerified', 'true');
|
||||
assert.fieldEquals('AccessPoint', 'thirdAP', 'nameVerified', 'true');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,109 +1,100 @@
|
|||
import {
|
||||
assert,
|
||||
describe,
|
||||
test,
|
||||
clearStore,
|
||||
beforeAll,
|
||||
afterAll,
|
||||
} from 'matchstick-as/assembly/index';
|
||||
import { BigInt, Bytes } from '@graphprotocol/graph-ts';
|
||||
import { createNewAccessPointEvent, handleNewAccessPoints, makeEventId, USER_ONE, USER_TWO } from '../helpers/utils';
|
||||
assert,
|
||||
describe,
|
||||
test,
|
||||
clearStore,
|
||||
beforeAll,
|
||||
afterAll,
|
||||
} from 'matchstick-as/assembly/index';
|
||||
import { BigInt, Bytes } from '@graphprotocol/graph-ts';
|
||||
import {
|
||||
createNewAccessPointEvent,
|
||||
handleNewAccessPoints,
|
||||
makeEventId,
|
||||
USER_ONE,
|
||||
USER_TWO,
|
||||
} from '../helpers/utils';
|
||||
import { NewAccessPoint } from '../../../generated/FleekNFA/FleekNFA';
|
||||
|
||||
describe('New Access Point tests', () => {
|
||||
beforeAll(() => {
|
||||
// New Access Points
|
||||
let newAccessPoints: NewAccessPoint[] = [];
|
||||
beforeAll(() => {
|
||||
// New Access Points
|
||||
let newAccessPoints: NewAccessPoint[] = [];
|
||||
|
||||
// User One has two access points: one for tokenId 0 and one for tokenId 1
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE)
|
||||
);
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE)
|
||||
);
|
||||
// User One has two access points: one for tokenId 0 and one for tokenId 1
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE)
|
||||
);
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE)
|
||||
);
|
||||
|
||||
// User Two has one access point for tokenId 0
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO)
|
||||
);
|
||||
handleNewAccessPoints(newAccessPoints);
|
||||
// User Two has one access point for tokenId 0
|
||||
newAccessPoints.push(
|
||||
createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO)
|
||||
);
|
||||
handleNewAccessPoints(newAccessPoints);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
clearStore();
|
||||
});
|
||||
|
||||
describe('Assertions', () => {
|
||||
test('Check the number of `NewAccessPoint` events to be valid', () => {
|
||||
assert.entityCount('NewAccessPoint', 3);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
clearStore();
|
||||
|
||||
test('Check the `apName` field of each event', () => {
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(0),
|
||||
'apName',
|
||||
'firstAP'.toString()
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(1),
|
||||
'apName',
|
||||
'secondAP'.toString()
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(2),
|
||||
'apName',
|
||||
'thirdAP'.toString()
|
||||
);
|
||||
});
|
||||
|
||||
describe('Assertions', () => {
|
||||
test('Check the number of `NewAccessPoint` events to be valid', () => {
|
||||
assert.entityCount('NewAccessPoint', 3);
|
||||
});
|
||||
|
||||
test('Check the `apName` field of each event', () => {
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(0),
|
||||
'apName',
|
||||
'firstAP'.toString()
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(1),
|
||||
'apName',
|
||||
'secondAP'.toString()
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(2),
|
||||
'apName',
|
||||
'thirdAP'.toString()
|
||||
);
|
||||
});
|
||||
|
||||
test('Check the `tokenId` field of each event', () => {
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(0),
|
||||
'tokenId',
|
||||
'0'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(1),
|
||||
'tokenId',
|
||||
'1'
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(2),
|
||||
'tokenId',
|
||||
'0'
|
||||
);
|
||||
});
|
||||
|
||||
test('Check the `owner` field of each event', () => {
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(0),
|
||||
'owner',
|
||||
USER_ONE.toString()
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(1),
|
||||
'owner',
|
||||
USER_ONE.toString()
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(2),
|
||||
'owner',
|
||||
USER_TWO.toString()
|
||||
);
|
||||
});
|
||||
|
||||
test('check the existence of a nonexistent event in the database', () => {
|
||||
assert.notInStore('NewAccessPoint', makeEventId(3));
|
||||
});
|
||||
test('Check the `tokenId` field of each event', () => {
|
||||
assert.fieldEquals('NewAccessPoint', makeEventId(0), 'tokenId', '0');
|
||||
assert.fieldEquals('NewAccessPoint', makeEventId(1), 'tokenId', '1');
|
||||
assert.fieldEquals('NewAccessPoint', makeEventId(2), 'tokenId', '0');
|
||||
});
|
||||
});
|
||||
|
||||
test('Check the `owner` field of each event', () => {
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(0),
|
||||
'owner',
|
||||
USER_ONE.toString()
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(1),
|
||||
'owner',
|
||||
USER_ONE.toString()
|
||||
);
|
||||
assert.fieldEquals(
|
||||
'NewAccessPoint',
|
||||
makeEventId(2),
|
||||
'owner',
|
||||
USER_TWO.toString()
|
||||
);
|
||||
});
|
||||
|
||||
test('check the existence of a nonexistent event in the database', () => {
|
||||
assert.notInStore('NewAccessPoint', makeEventId(3));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
ChangeAccessPointNameVerify,
|
||||
TokenRoleChanged,
|
||||
CollectionRoleChanged,
|
||||
TokenRolesCleared
|
||||
TokenRolesCleared,
|
||||
} from '../../../generated/FleekNFA/FleekNFA';
|
||||
import {
|
||||
handleApproval,
|
||||
|
|
@ -198,10 +198,7 @@ export function createNewAccessPointEvent(
|
|||
);
|
||||
|
||||
newAccessPoint.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
'owner',
|
||||
ethereum.Value.fromAddress(owner)
|
||||
)
|
||||
new ethereum.EventParam('owner', ethereum.Value.fromAddress(owner))
|
||||
);
|
||||
|
||||
newAccessPoint.transaction.hash = Bytes.fromI32(event_count);
|
||||
|
|
@ -217,7 +214,8 @@ export function createNewChangeAccessPointCreationStatus(
|
|||
status: i32,
|
||||
triggeredBy: Address
|
||||
): ChangeAccessPointCreationStatus {
|
||||
let changeAccessPointCreationStatus = changetype<ChangeAccessPointCreationStatus>(newMockEvent());
|
||||
let changeAccessPointCreationStatus =
|
||||
changetype<ChangeAccessPointCreationStatus>(newMockEvent());
|
||||
|
||||
changeAccessPointCreationStatus.parameters = new Array();
|
||||
|
||||
|
|
@ -236,10 +234,7 @@ export function createNewChangeAccessPointCreationStatus(
|
|||
);
|
||||
|
||||
changeAccessPointCreationStatus.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
'creationStatus',
|
||||
ethereum.Value.fromI32(status)
|
||||
)
|
||||
new ethereum.EventParam('creationStatus', ethereum.Value.fromI32(status))
|
||||
);
|
||||
|
||||
changeAccessPointCreationStatus.parameters.push(
|
||||
|
|
@ -262,7 +257,9 @@ export function createNewChangeAccessPointNameVerify(
|
|||
verified: boolean,
|
||||
triggeredBy: Address
|
||||
): ChangeAccessPointNameVerify {
|
||||
let changeAccessPointNameVerify = changetype<ChangeAccessPointNameVerify>(newMockEvent());
|
||||
let changeAccessPointNameVerify = changetype<ChangeAccessPointNameVerify>(
|
||||
newMockEvent()
|
||||
);
|
||||
|
||||
changeAccessPointNameVerify.parameters = new Array();
|
||||
|
||||
|
|
@ -281,10 +278,7 @@ export function createNewChangeAccessPointNameVerify(
|
|||
);
|
||||
|
||||
changeAccessPointNameVerify.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
'verified',
|
||||
ethereum.Value.fromBoolean(verified)
|
||||
)
|
||||
new ethereum.EventParam('verified', ethereum.Value.fromBoolean(verified))
|
||||
);
|
||||
|
||||
changeAccessPointNameVerify.parameters.push(
|
||||
|
|
@ -320,31 +314,19 @@ export function createNewTokenRoleChanged(
|
|||
);
|
||||
|
||||
tokenRoleChanged.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
'role',
|
||||
ethereum.Value.fromI32(role)
|
||||
)
|
||||
new ethereum.EventParam('role', ethereum.Value.fromI32(role))
|
||||
);
|
||||
|
||||
tokenRoleChanged.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
'toAddress',
|
||||
ethereum.Value.fromAddress(toAddress)
|
||||
)
|
||||
new ethereum.EventParam('toAddress', ethereum.Value.fromAddress(toAddress))
|
||||
);
|
||||
|
||||
tokenRoleChanged.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
'status',
|
||||
ethereum.Value.fromBoolean(status)
|
||||
)
|
||||
new ethereum.EventParam('status', ethereum.Value.fromBoolean(status))
|
||||
);
|
||||
|
||||
tokenRoleChanged.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
'byAddress',
|
||||
ethereum.Value.fromAddress(byAddress)
|
||||
)
|
||||
new ethereum.EventParam('byAddress', ethereum.Value.fromAddress(byAddress))
|
||||
);
|
||||
|
||||
tokenRoleChanged.transaction.hash = Bytes.fromI32(event_count);
|
||||
|
|
@ -365,31 +347,19 @@ export function createNewCollectionRoleChanged(
|
|||
collectionRoleChanged.parameters = new Array();
|
||||
|
||||
collectionRoleChanged.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
'role',
|
||||
ethereum.Value.fromI32(role)
|
||||
)
|
||||
new ethereum.EventParam('role', ethereum.Value.fromI32(role))
|
||||
);
|
||||
|
||||
collectionRoleChanged.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
'toAddress',
|
||||
ethereum.Value.fromAddress(toAddress)
|
||||
)
|
||||
new ethereum.EventParam('toAddress', ethereum.Value.fromAddress(toAddress))
|
||||
);
|
||||
|
||||
collectionRoleChanged.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
'status',
|
||||
ethereum.Value.fromBoolean(status)
|
||||
)
|
||||
new ethereum.EventParam('status', ethereum.Value.fromBoolean(status))
|
||||
);
|
||||
|
||||
collectionRoleChanged.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
'byAddress',
|
||||
ethereum.Value.fromAddress(byAddress)
|
||||
)
|
||||
new ethereum.EventParam('byAddress', ethereum.Value.fromAddress(byAddress))
|
||||
);
|
||||
|
||||
collectionRoleChanged.transaction.hash = Bytes.fromI32(event_count);
|
||||
|
|
@ -400,8 +370,8 @@ export function createNewCollectionRoleChanged(
|
|||
|
||||
export function createNewTokenRolesCleared(
|
||||
event_count: i32,
|
||||
tokenId: BigInt,
|
||||
byAddress: Address
|
||||
tokenId: BigInt,
|
||||
byAddress: Address
|
||||
): TokenRolesCleared {
|
||||
let tokenRolesCleared = changetype<TokenRolesCleared>(newMockEvent());
|
||||
|
||||
|
|
@ -415,10 +385,7 @@ export function createNewTokenRolesCleared(
|
|||
);
|
||||
|
||||
tokenRolesCleared.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
'byAddress',
|
||||
ethereum.Value.fromAddress(byAddress)
|
||||
)
|
||||
new ethereum.EventParam('byAddress', ethereum.Value.fromAddress(byAddress))
|
||||
);
|
||||
|
||||
tokenRolesCleared.transaction.hash = Bytes.fromI32(event_count);
|
||||
|
|
@ -470,13 +437,17 @@ export function handleNewAccessPoints(events: NewAccessPoint[]): void {
|
|||
});
|
||||
}
|
||||
|
||||
export function handleChangeAccessPointCreationStatusList(events: ChangeAccessPointCreationStatus[]): void {
|
||||
export function handleChangeAccessPointCreationStatusList(
|
||||
events: ChangeAccessPointCreationStatus[]
|
||||
): void {
|
||||
events.forEach((event) => {
|
||||
handleChangeAccessPointCreationStatus(event);
|
||||
});
|
||||
}
|
||||
|
||||
export function handleChangeAccessPointNameVerifies(events: ChangeAccessPointNameVerify[]): void {
|
||||
export function handleChangeAccessPointNameVerifies(
|
||||
events: ChangeAccessPointNameVerify[]
|
||||
): void {
|
||||
events.forEach((event) => {
|
||||
handleChangeAccessPointNameVerify(event);
|
||||
});
|
||||
|
|
@ -488,7 +459,9 @@ export function handleTokenRoleChangedList(events: TokenRoleChanged[]): void {
|
|||
});
|
||||
}
|
||||
|
||||
export function handleCollectionRoleChangedList(events: CollectionRoleChanged[]): void {
|
||||
export function handleCollectionRoleChangedList(
|
||||
events: CollectionRoleChanged[]
|
||||
): void {
|
||||
events.forEach((event) => {
|
||||
handleCollectionRoleChanged(event);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -46,23 +46,13 @@ describe('Owner tests', () => {
|
|||
createTransferEvent(3, CONTRACT, USER_ONE, BigInt.fromI32(3))
|
||||
);
|
||||
transfers.push(
|
||||
createTransferEvent(
|
||||
4,
|
||||
USER_TWO,
|
||||
USER_ONE,
|
||||
BigInt.fromI32(1)
|
||||
)
|
||||
createTransferEvent(4, USER_TWO, USER_ONE, BigInt.fromI32(1))
|
||||
);
|
||||
transfers.push(
|
||||
createTransferEvent(5, CONTRACT, USER_TWO, BigInt.fromI32(4))
|
||||
);
|
||||
transfers.push(
|
||||
createTransferEvent(
|
||||
6,
|
||||
USER_ONE,
|
||||
USER_TWO,
|
||||
BigInt.fromI32(0)
|
||||
)
|
||||
createTransferEvent(6, USER_ONE, USER_TWO, BigInt.fromI32(0))
|
||||
);
|
||||
handleTransfers(transfers);
|
||||
//logStore();
|
||||
|
|
|
|||
|
|
@ -36,23 +36,13 @@ describe('Transfer tests', () => {
|
|||
createTransferEvent(3, CONTRACT, USER_ONE, BigInt.fromI32(3))
|
||||
);
|
||||
transfers.push(
|
||||
createTransferEvent(
|
||||
4,
|
||||
USER_TWO,
|
||||
USER_ONE,
|
||||
BigInt.fromI32(1)
|
||||
)
|
||||
createTransferEvent(4, USER_TWO, USER_ONE, BigInt.fromI32(1))
|
||||
);
|
||||
transfers.push(
|
||||
createTransferEvent(5, CONTRACT, USER_TWO, BigInt.fromI32(4))
|
||||
);
|
||||
transfers.push(
|
||||
createTransferEvent(
|
||||
6,
|
||||
USER_ONE,
|
||||
USER_TWO,
|
||||
BigInt.fromI32(0)
|
||||
)
|
||||
createTransferEvent(6, USER_ONE, USER_TWO, BigInt.fromI32(0))
|
||||
);
|
||||
handleTransfers(transfers);
|
||||
// logStore();
|
||||
|
|
|
|||
Loading…
Reference in New Issue