diff --git a/package.json b/package.json index 38f29b01..a2f0bde9 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,10 @@ }, "devDependencies": { "@babel/preset-typescript": "^7.23.3", - "@truffle/hdwallet-provider": "^2.1.11", + "@truffle/hdwallet-provider": "^2.1.15", "@types/chai": "^4.3.0", "@types/crypto-js": "^4.0.2", + "@types/ethereumjs-abi": "^0.6.5", "@types/jest": "^29.5.12", "@types/mime-types": "^2.1.4", "@types/mocha": "^9.1.0", @@ -61,6 +62,7 @@ "axios": "^0.27.2", "crypto": "^1.0.1", "crypto-js": "^4.1.1", + "ethereumjs-abi": "^0.6.8", "ethers": "5.7.2", "fetch-blob": "^4.0.0", "form-data": "^4.0.0", diff --git a/src/contract/VWBLERC6150ERC2981.json b/src/contract/VWBLERC6150ERC2981.json new file mode 100644 index 00000000..da9c305b --- /dev/null +++ b/src/contract/VWBLERC6150ERC2981.json @@ -0,0 +1,1161 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "VWBLERC6150ERC2981", + "sourceName": "contracts/access-condition/ERC6150/VWBLERC6150ERC2981.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_baseURI", + "type": "string" + }, + { + "internalType": "address", + "name": "_gatewayProxy", + "type": "address" + }, + { + "internalType": "address", + "name": "_accessCheckerContract", + "type": "address" + }, + { + "internalType": "string", + "name": "_signMessage", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "grantee", + "type": "address" + } + ], + "name": "AncestorPermissionGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "revoker", + "type": "address" + } + ], + "name": "AncestorPermissionRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "parentId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Minted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldParentId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newParentId", + "type": "uint256" + } + ], + "name": "ParentTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "grantee", + "type": "address" + } + ], + "name": "ViewPermissionGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "revoker", + "type": "address" + } + ], + "name": "ViewPermissionRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessCheckerContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessCheckerContract", + "type": "address" + } + ], + "name": "accessCheckerContractChanged", + "type": "event" + }, + { + "inputs": [], + "name": "accessCheckerContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newParentId", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "tokenIds", + "type": "uint256[]" + } + ], + "name": "batchTransferParent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "checkDirPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "checkViewPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "childrenOf", + "outputs": [ + { + "internalType": "uint256[]", + "name": "childrenIds", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "counter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gatewayProxy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllowOrigins", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getGatewayAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getMinter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSignMessage", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "getTokenByMinter", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "grantee", + "type": "address" + }, + { + "internalType": "bool", + "name": "toDir", + "type": "bool" + } + ], + "name": "grantViewPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "grantee", + "type": "address" + } + ], + "name": "grantViewPermissionToDir", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "hasDirPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "hasViewPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "isLeaf", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "isRoot", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_getKeyURl", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_parentId", + "type": "uint256" + }, + { + "internalType": "uint96", + "name": "_feeNumerator", + "type": "uint96" + }, + { + "internalType": "bytes32", + "name": "_documentId", + "type": "bytes32" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "parentOf", + "outputs": [ + { + "internalType": "uint256", + "name": "parentId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "revoker", + "type": "address" + } + ], + "name": "revokeDirPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "revoker", + "type": "address" + } + ], + "name": "revokeViewPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_salePrice", + "type": "uint256" + } + ], + "name": "royaltyInfo", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAccessCheckerContract", + "type": "address" + } + ], + "name": "setAccessCheckerContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_origins", + "type": "string" + } + ], + "name": "setAllowOrigins", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_baseURI", + "type": "string" + } + ], + "name": "setBaseURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_signMessage", + "type": "string" + } + ], + "name": "setSignMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "tokenIdToTokenInfo", + "outputs": [ + { + "internalType": "bytes32", + "name": "documentId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "minterAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "getKeyURl", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newParentId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferParent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} \ No newline at end of file diff --git a/src/contract/VWBLERC6150ERC2981ForMetadata.json b/src/contract/VWBLERC6150ERC2981ForMetadata.json new file mode 100644 index 00000000..107e6b6f --- /dev/null +++ b/src/contract/VWBLERC6150ERC2981ForMetadata.json @@ -0,0 +1,1161 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "VWBLERC6150ERC2981ForMetadata", + "sourceName": "contracts/access-condition/ERC6150/extensions/VWBLERC6150ERC2981ForMetadata.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_gatewayProxy", + "type": "address" + }, + { + "internalType": "address", + "name": "_accessCheckerContract", + "type": "address" + }, + { + "internalType": "string", + "name": "_signMessage", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "grantee", + "type": "address" + } + ], + "name": "AncestorPermissionGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "revoker", + "type": "address" + } + ], + "name": "AncestorPermissionRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "parentId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Minted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldParentId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newParentId", + "type": "uint256" + } + ], + "name": "ParentTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "grantee", + "type": "address" + } + ], + "name": "ViewPermissionGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "revoker", + "type": "address" + } + ], + "name": "ViewPermissionRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessCheckerContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessCheckerContract", + "type": "address" + } + ], + "name": "accessCheckerContractChanged", + "type": "event" + }, + { + "inputs": [], + "name": "accessCheckerContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newParentId", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "tokenIds", + "type": "uint256[]" + } + ], + "name": "batchTransferParent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "checkDirPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "checkViewPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "childrenOf", + "outputs": [ + { + "internalType": "uint256[]", + "name": "childrenIds", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "counter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gatewayProxy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllowOrigins", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getGatewayAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getMinter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSignMessage", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "getTokenByMinter", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "grantee", + "type": "address" + }, + { + "internalType": "bool", + "name": "toDir", + "type": "bool" + } + ], + "name": "grantViewPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "grantee", + "type": "address" + } + ], + "name": "grantViewPermissionToDir", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "hasDirPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "hasViewPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "isLeaf", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "isRoot", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_metadataURL", + "type": "string" + }, + { + "internalType": "string", + "name": "_getKeyURl", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_parentId", + "type": "uint256" + }, + { + "internalType": "uint96", + "name": "_feeNumerator", + "type": "uint96" + }, + { + "internalType": "bytes32", + "name": "_documentId", + "type": "bytes32" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "parentOf", + "outputs": [ + { + "internalType": "uint256", + "name": "parentId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "revoker", + "type": "address" + } + ], + "name": "revokeDirPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "revoker", + "type": "address" + } + ], + "name": "revokeViewPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_salePrice", + "type": "uint256" + } + ], + "name": "royaltyInfo", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAccessCheckerContract", + "type": "address" + } + ], + "name": "setAccessCheckerContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_origins", + "type": "string" + } + ], + "name": "setAllowOrigins", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_baseURI", + "type": "string" + } + ], + "name": "setBaseURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_signMessage", + "type": "string" + } + ], + "name": "setSignMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "tokenIdToTokenInfo", + "outputs": [ + { + "internalType": "bytes32", + "name": "documentId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "minterAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "getKeyURl", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newParentId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferParent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} \ No newline at end of file diff --git a/src/contract/VWBLERC721ERC2981.json b/src/contract/VWBLERC721ERC2981.json index 8f3573b8..f06f64e4 100644 --- a/src/contract/VWBLERC721ERC2981.json +++ b/src/contract/VWBLERC721ERC2981.json @@ -3,6 +3,30 @@ "contractName": "VWBLERC721ERC2981", "sourceName": "contracts/access-condition/ERC721/VWBLERC721ERC2981.sol", "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "revoker", + "type": "address" + } + ], + "name": "revokeViewPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -766,6 +790,54 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "grantee", + "type": "address" + } + ], + "name": "grantViewPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "checkViewPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" } ], "bytecode": "0x608060405260006006553480156200001657600080fd5b5060405162002d2338038062002d23833981016040819052620000399162000256565b604051806040016040528060048152602001631595d09360e21b815250604051806040016040528060048152602001631595d09360e21b81525085858585828282620000946200008e6200012060201b60201c565b62000124565b600180546001600160a01b0319166001600160a01b0385161790556002620000bd828262000374565b5050600480546001600160a01b0319166001600160a01b0392909216919091179055506005620000ee858262000374565b5050505050816008908162000104919062000374565b50600962000113828262000374565b5050505050505062000440565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200019c57600080fd5b81516001600160401b0380821115620001b957620001b962000174565b604051601f8301601f19908116603f01168101908282118183101715620001e457620001e462000174565b816040528381526020925086838588010111156200020157600080fd5b600091505b8382101562000225578582018301518183018401529082019062000206565b600093810190920192909252949350505050565b80516001600160a01b03811681146200025157600080fd5b919050565b600080600080608085870312156200026d57600080fd5b84516001600160401b03808211156200028557600080fd5b62000293888389016200018a565b9550620002a36020880162000239565b9450620002b36040880162000239565b93506060870151915080821115620002ca57600080fd5b50620002d9878288016200018a565b91505092959194509250565b600181811c90821680620002fa57607f821691505b6020821081036200031b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200036f57600081815260208120601f850160051c810160208610156200034a5750805b601f850160051c820191505b818110156200036b5782815560010162000356565b5050505b505050565b81516001600160401b0381111562000390576200039062000174565b620003a881620003a18454620002e5565b8462000321565b602080601f831160018114620003e05760008415620003c75750858301515b600019600386901b1c1916600185901b1785556200036b565b600085815260208120601f198616915b828110156200041157888601518255948401946001909101908401620003f0565b5085821015620004305787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6128d380620004506000396000f3fe60806040526004361061020f5760003560e01c80636352211e11610118578063a22cb465116100a0578063ce5af3361161006f578063ce5af3361461061b578063ced72f8714610648578063d185f5201461065d578063e985e9c514610672578063f2fde38b146106bb57600080fd5b8063a22cb4651461059b578063b41bde13146105bb578063b88d4fde146105db578063c87b56dd146105fb57600080fd5b80637db551b0116100e75780637db551b0146105135780638da5cb5b1461052857806393fab57b1461054657806395d89b41146105665780639ab5e9751461057b57600080fd5b80636352211e146104a95780636c0360eb146104c957806370a08231146104de578063715018a6146104fe57600080fd5b8063357113461161019b57806355f804b31161016a57806355f804b3146103eb5780635a920f061461040b5780635b7121f81461042b5780635fb8bcd51461046457806361bc221a1461049357600080fd5b806335711346146103835780633adda02c1461039857806342842e0e146103ab5780634f6ccce7146103cb57600080fd5b806318160ddd116101e257806318160ddd146102c557806323b872dd146102e45780632812a3d2146103045780632a55205a146103245780632f745c591461036357600080fd5b806301ffc9a71461021457806306fdde0314610249578063081812fc1461026b578063095ea7b3146102a3575b600080fd5b34801561022057600080fd5b5061023461022f366004611fd3565b6106db565b60405190151581526020015b60405180910390f35b34801561025557600080fd5b5061025e6106ec565b6040516102409190612040565b34801561027757600080fd5b5061028b610286366004612053565b61077e565b6040516001600160a01b039091168152602001610240565b3480156102af57600080fd5b506102c36102be366004612081565b6107a5565b005b3480156102d157600080fd5b506010545b604051908152602001610240565b3480156102f057600080fd5b506102c36102ff3660046120ad565b6108bf565b34801561031057600080fd5b506102c361031f3660046120ee565b6108f0565b34801561033057600080fd5b5061034461033f36600461210b565b610974565b604080516001600160a01b039093168352602083019190915201610240565b34801561036f57600080fd5b506102d661037e366004612081565b610a20565b34801561038f57600080fd5b5061028b610ab6565b6102d66103a63660046121d9565b610b29565b3480156103b757600080fd5b506102c36103c63660046120ad565b610c45565b3480156103d757600080fd5b506102d66103e6366004612053565b610c60565b3480156103f757600080fd5b506102c361040636600461222e565b610cf3565b34801561041757600080fd5b506102c361042636600461222e565b610d0b565b34801561043757600080fd5b5061028b610446366004612053565b6000908152600760205260409020600101546001600160a01b031690565b34801561047057600080fd5b5061048461047f366004612053565b610d1f565b60405161024093929190612263565b34801561049f57600080fd5b506102d660065481565b3480156104b557600080fd5b5061028b6104c4366004612053565b610dd4565b3480156104d557600080fd5b5061025e610e34565b3480156104ea57600080fd5b506102d66104f93660046120ee565b610ec2565b34801561050a57600080fd5b506102c3610f48565b34801561051f57600080fd5b5061025e610f5c565b34801561053457600080fd5b506000546001600160a01b031661028b565b34801561055257600080fd5b5060045461028b906001600160a01b031681565b34801561057257600080fd5b5061025e610f6b565b34801561058757600080fd5b506102c3610596366004612296565b610f7a565b3480156105a757600080fd5b506102c36105b6366004612308565b610f8f565b3480156105c757600080fd5b5060015461028b906001600160a01b031681565b3480156105e757600080fd5b506102c36105f6366004612346565b610f9a565b34801561060757600080fd5b5061025e610616366004612053565b610fd2565b34801561062757600080fd5b5061063b6106363660046120ee565b611039565b60405161024091906123c6565b34801561065457600080fd5b506102d661114e565b34801561066957600080fd5b5061025e6111b9565b34801561067e57600080fd5b5061023461068d36600461240a565b6001600160a01b039182166000908152600d6020908152604080832093909416825291909152205460ff1690565b3480156106c757600080fd5b506102c36106d63660046120ee565b6111c8565b60006106e682611241565b92915050565b6060600880546106fb90612438565b80601f016020809104026020016040519081016040528092919081815260200182805461072790612438565b80156107745780601f1061074957610100808354040283529160200191610774565b820191906000526020600020905b81548152906001019060200180831161075757829003601f168201915b5050505050905090565b600061078982611266565b506000908152600c60205260409020546001600160a01b031690565b60006107b082610dd4565b9050806001600160a01b0316836001600160a01b0316036108225760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061083e575061083e813361068d565b6108b05760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610819565b6108ba83836112c5565b505050565b6108c93382611333565b6108e55760405162461bcd60e51b815260040161081990612472565b6108ba8383836113b2565b6108f8611523565b6004546001600160a01b039081169082160361091357600080fd5b600480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f9aaef5934caac7bf8ee7de13d1a1e98122180cb78e64abeae728ad559df64a66910160405180910390a15050565b60008281526013602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916109e95750604080518082019091526012546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610a08906001600160601b0316876124d5565b610a1291906124ec565b915196919550909350505050565b6000610a2b83610ec2565b8210610a8d5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610819565b506001600160a01b03919091166000908152600e60209081526040808320938352929052205490565b60015460408051631ab889a360e11b815290516000926001600160a01b03169163357113469160048083019260209291908290030181865afa158015610b00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b24919061250e565b905090565b600080600660008154610b3b9061252b565b9182905550604080516060810182528581523360208083019182528284018a8152600086815260079092529390208251815590516001820180546001600160a01b0319166001600160a01b039092169190911790559151929350918291906002820190610ba89082612592565b50905050610bb6338361157d565b6001600160601b03851615610bd057610bd0823387611716565b60048054604051630f384cd960e01b8152918201869052306024830152604482018490526001600160a01b031690630f384cd99034906064016000604051808303818588803b158015610c2257600080fd5b505af1158015610c36573d6000803e3d6000fd5b50949998505050505050505050565b6108ba83838360405180602001604052806000815250610f9a565b6000610c6b60105490565b8210610cce5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610819565b60108281548110610ce157610ce1612652565b90600052602060002001549050919050565b610cfb611523565b6005610d078282612592565b5050565b610d13611523565b6003610d078282612592565b60076020526000908152604090208054600182015460028301805492936001600160a01b0390921692610d5190612438565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7d90612438565b8015610dca5780601f10610d9f57610100808354040283529160200191610dca565b820191906000526020600020905b815481529060010190602001808311610dad57829003601f168201915b5050505050905083565b6000818152600a60205260408120546001600160a01b0316806106e65760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610819565b60058054610e4190612438565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6d90612438565b8015610eba5780601f10610e8f57610100808354040283529160200191610eba565b820191906000526020600020905b815481529060010190602001808311610e9d57829003601f168201915b505050505081565b60006001600160a01b038216610f2c5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610819565b506001600160a01b03166000908152600b602052604090205490565b610f50611523565b610f5a6000611824565b565b6060600280546106fb90612438565b6060600980546106fb90612438565b610f82611523565b60026108ba828483612668565b610d07338383611874565b610fa43383611333565b610fc05760405162461bcd60e51b815260040161081990612472565b610fcc84848484611942565b50505050565b6060610fdd82611266565b6000610fe7611975565b905060008151116110075760405180602001604052806000815250611032565b8061101184611984565b604051602001611022929190612728565b6040516020818303038152906040525b9392505050565b6060600060015b600654811161108d576000818152600760205260409020600101546001600160a01b0380861691160361107b57816110778161252b565b9250505b806110858161252b565b915050611040565b5060008167ffffffffffffffff8111156110a9576110a961212d565b6040519080825280602002602001820160405280156110d2578160200160208202803683370190505b509050600060015b6006548111611144576000818152600760205260409020600101546001600160a01b03808816911603611132578083836111138161252b565b94508151811061112557611125612652565b6020026020010181815250505b8061113c8161252b565b9150506110da565b5090949350505050565b6000611158610ab6565b6001600160a01b031663428c090b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611195573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b249190612757565b6060600380546106fb90612438565b6111d0611523565b6001600160a01b0381166112355760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610819565b61123e81611824565b50565b60006001600160e01b0319821663152a902d60e11b14806106e657506106e682611a17565b6000818152600a60205260409020546001600160a01b031661123e5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610819565b6000818152600c6020526040902080546001600160a01b0319166001600160a01b03841690811790915581906112fa82610dd4565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061133f83610dd4565b9050806001600160a01b0316846001600160a01b0316148061138657506001600160a01b038082166000908152600d602090815260408083209388168352929052205460ff165b806113aa5750836001600160a01b031661139f8461077e565b6001600160a01b0316145b949350505050565b826001600160a01b03166113c582610dd4565b6001600160a01b0316146113eb5760405162461bcd60e51b815260040161081990612770565b6001600160a01b03821661144d5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610819565b61145a8383836001611a3c565b826001600160a01b031661146d82610dd4565b6001600160a01b0316146114935760405162461bcd60e51b815260040161081990612770565b6000818152600c6020908152604080832080546001600160a01b03199081169091556001600160a01b03878116808652600b8552838620805460001901905590871680865283862080546001019055868652600a90945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000546001600160a01b03163314610f5a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610819565b6001600160a01b0382166115d35760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610819565b6000818152600a60205260409020546001600160a01b0316156116385760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610819565b611646600083836001611a3c565b6000818152600a60205260409020546001600160a01b0316156116ab5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610819565b6001600160a01b0382166000818152600b6020908152604080832080546001019055848352600a90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6127106001600160601b03821611156117845760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610819565b6001600160a01b0382166117da5760405162461bcd60e51b815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152606401610819565b6040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182526000968752601390529190942093519051909116600160a01b029116179055565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b816001600160a01b0316836001600160a01b0316036118d55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610819565b6001600160a01b038381166000818152600d6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61194d8484846113b2565b61195984848484611b7c565b610fcc5760405162461bcd60e51b8152600401610819906127b5565b6060600580546106fb90612438565b6060600061199183611c7d565b600101905060008167ffffffffffffffff8111156119b1576119b161212d565b6040519080825280601f01601f1916602001820160405280156119db576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846119e557509392505050565b60006001600160e01b0319821663780e9d6360e01b14806106e657506106e682611d55565b611a4884848484611da5565b6001811115611ab75760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610819565b816001600160a01b038516611b1357611b0e81601080546000838152601160205260408120829055600182018355919091527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6720155565b611b36565b836001600160a01b0316856001600160a01b031614611b3657611b368582611e2d565b6001600160a01b038416611b5257611b4d81611eca565b611b75565b846001600160a01b0316846001600160a01b031614611b7557611b758482611f79565b5050505050565b60006001600160a01b0384163b15611c7257604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611bc0903390899088908890600401612807565b6020604051808303816000875af1925050508015611bfb575060408051601f3d908101601f19168201909252611bf891810190612844565b60015b611c58573d808015611c29576040519150601f19603f3d011682016040523d82523d6000602084013e611c2e565b606091505b508051600003611c505760405162461bcd60e51b8152600401610819906127b5565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506113aa565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611cbc5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611ce8576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611d0657662386f26fc10000830492506010015b6305f5e1008310611d1e576305f5e100830492506008015b6127108310611d3257612710830492506004015b60648310611d44576064830492506002015b600a83106106e65760010192915050565b60006001600160e01b031982166380ac58cd60e01b1480611d8657506001600160e01b03198216635b5e139f60e01b145b806106e657506301ffc9a760e01b6001600160e01b03198316146106e6565b6001811115610fcc576001600160a01b03841615611deb576001600160a01b0384166000908152600b602052604081208054839290611de5908490612861565b90915550505b6001600160a01b03831615610fcc576001600160a01b0383166000908152600b602052604081208054839290611e22908490612874565b909155505050505050565b60006001611e3a84610ec2565b611e449190612861565b6000838152600f6020526040902054909150808214611e97576001600160a01b0384166000908152600e602090815260408083208584528252808320548484528184208190558352600f90915290208190555b506000918252600f602090815260408084208490556001600160a01b039094168352600e81528383209183525290812055565b601054600090611edc90600190612861565b60008381526011602052604081205460108054939450909284908110611f0457611f04612652565b906000526020600020015490508060108381548110611f2557611f25612652565b6000918252602080832090910192909255828152601190915260408082208490558582528120556010805480611f5d57611f5d612887565b6001900381819060005260206000200160009055905550505050565b6000611f8483610ec2565b6001600160a01b039093166000908152600e602090815260408083208684528252808320859055938252600f9052919091209190915550565b6001600160e01b03198116811461123e57600080fd5b600060208284031215611fe557600080fd5b813561103281611fbd565b60005b8381101561200b578181015183820152602001611ff3565b50506000910152565b6000815180845261202c816020860160208601611ff0565b601f01601f19169290920160200192915050565b6020815260006110326020830184612014565b60006020828403121561206557600080fd5b5035919050565b6001600160a01b038116811461123e57600080fd5b6000806040838503121561209457600080fd5b823561209f8161206c565b946020939093013593505050565b6000806000606084860312156120c257600080fd5b83356120cd8161206c565b925060208401356120dd8161206c565b929592945050506040919091013590565b60006020828403121561210057600080fd5b81356110328161206c565b6000806040838503121561211e57600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff8084111561215e5761215e61212d565b604051601f8501601f19908116603f011681019082821181831017156121865761218661212d565b8160405280935085815286868601111561219f57600080fd5b858560208301376000602087830101525050509392505050565b600082601f8301126121ca57600080fd5b61103283833560208501612143565b6000806000606084860312156121ee57600080fd5b833567ffffffffffffffff81111561220557600080fd5b612211868287016121b9565b93505060208401356001600160601b03811681146120dd57600080fd5b60006020828403121561224057600080fd5b813567ffffffffffffffff81111561225757600080fd5b6113aa848285016121b9565b8381526001600160a01b038316602082015260606040820181905260009061228d90830184612014565b95945050505050565b600080602083850312156122a957600080fd5b823567ffffffffffffffff808211156122c157600080fd5b818501915085601f8301126122d557600080fd5b8135818111156122e457600080fd5b8660208285010111156122f657600080fd5b60209290920196919550909350505050565b6000806040838503121561231b57600080fd5b82356123268161206c565b91506020830135801515811461233b57600080fd5b809150509250929050565b6000806000806080858703121561235c57600080fd5b84356123678161206c565b935060208501356123778161206c565b925060408501359150606085013567ffffffffffffffff81111561239a57600080fd5b8501601f810187136123ab57600080fd5b6123ba87823560208401612143565b91505092959194509250565b6020808252825182820181905260009190848201906040850190845b818110156123fe578351835292840192918401916001016123e2565b50909695505050505050565b6000806040838503121561241d57600080fd5b82356124288161206c565b9150602083013561233b8161206c565b600181811c9082168061244c57607f821691505b60208210810361246c57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176106e6576106e66124bf565b60008261250957634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561252057600080fd5b81516110328161206c565b60006001820161253d5761253d6124bf565b5060010190565b601f8211156108ba57600081815260208120601f850160051c8101602086101561256b5750805b601f850160051c820191505b8181101561258a57828155600101612577565b505050505050565b815167ffffffffffffffff8111156125ac576125ac61212d565b6125c0816125ba8454612438565b84612544565b602080601f8311600181146125f557600084156125dd5750858301515b600019600386901b1c1916600185901b17855561258a565b600085815260208120601f198616915b8281101561262457888601518255948401946001909101908401612605565b50858210156126425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b67ffffffffffffffff8311156126805761268061212d565b6126948361268e8354612438565b83612544565b6000601f8411600181146126c857600085156126b05750838201355b600019600387901b1c1916600186901b178355611b75565b600083815260209020601f19861690835b828110156126f957868501358255602094850194600190920191016126d9565b50868210156127165760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6000835161273a818460208801611ff0565b83519083019061274e818360208801611ff0565b01949350505050565b60006020828403121561276957600080fd5b5051919050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061283a90830184612014565b9695505050505050565b60006020828403121561285657600080fd5b815161103281611fbd565b818103818111156106e6576106e66124bf565b808201808211156106e6576106e66124bf565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220a89eba7e86e33d63ca5483f3412e3180ca7db451d28082a0658b028fb15cbc7d64736f6c63430008110033", diff --git a/src/contract/VWBLERC721ERC2981ForMetadata.json b/src/contract/VWBLERC721ERC2981ForMetadata.json index 38a90e29..291c3366 100644 --- a/src/contract/VWBLERC721ERC2981ForMetadata.json +++ b/src/contract/VWBLERC721ERC2981ForMetadata.json @@ -3,6 +3,30 @@ "contractName": "VWBLERC721ERC2981ForMetadata", "sourceName": "contracts/access-condition/ERC721/extensions/VWBLERC721ERC2981ForMetadata.sol", "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "revoker", + "type": "address" + } + ], + "name": "revokeViewPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -766,6 +790,54 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "grantee", + "type": "address" + } + ], + "name": "grantViewPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "checkViewPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" } ], "bytecode": "0x608060405260006006553480156200001657600080fd5b5060405162002be438038062002be48339810160408190526200003991620001b5565b604051806040016040528060048152602001631595d09360e21b815250604051806040016040528060048152602001631595d09360e21b81525060405180602001604052806000815250858585828282620000a36200009d6200012e60201b60201c565b62000132565b600180546001600160a01b0319166001600160a01b0385161790556002620000cc82826200033e565b5050600480546001600160a01b0319166001600160a01b0392909216919091179055506005620000fd85826200033e565b505050505081600890816200011391906200033e565b5060096200012282826200033e565b5050505050506200040a565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200019a57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080600060608486031215620001cb57600080fd5b620001d68462000182565b92506020620001e781860162000182565b60408601519093506001600160401b03808211156200020557600080fd5b818701915087601f8301126200021a57600080fd5b8151818111156200022f576200022f6200019f565b604051601f8201601f19908116603f011681019083821181831017156200025a576200025a6200019f565b816040528281528a868487010111156200027357600080fd5b600093505b8284101562000297578484018601518185018701529285019262000278565b60008684830101528096505050505050509250925092565b600181811c90821680620002c457607f821691505b602082108103620002e557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200033957600081815260208120601f850160051c81016020861015620003145750805b601f850160051c820191505b81811015620003355782815560010162000320565b5050505b505050565b81516001600160401b038111156200035a576200035a6200019f565b62000372816200036b8454620002af565b84620002eb565b602080601f831160018114620003aa5760008415620003915750858301515b600019600386901b1c1916600185901b17855562000335565b600085815260208120601f198616915b82811015620003db57888601518255948401946001909101908401620003ba565b5085821015620003fa5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6127ca806200041a6000396000f3fe60806040526004361061020f5760003560e01c80636352211e11610118578063a22cb465116100a0578063ce5af3361161006f578063ce5af3361461061b578063ced72f8714610648578063d185f5201461065d578063e985e9c514610672578063f2fde38b146106bb57600080fd5b8063a22cb4651461059b578063b41bde13146105bb578063b88d4fde146105db578063c87b56dd146105fb57600080fd5b80637db551b0116100e75780637db551b0146105135780638da5cb5b1461052857806393fab57b1461054657806395d89b41146105665780639ab5e9751461057b57600080fd5b80636352211e146104a95780636c0360eb146104c957806370a08231146104de578063715018a6146104fe57600080fd5b8063357113461161019b57806355f804b31161016a57806355f804b3146103eb5780635a920f061461040b5780635b7121f81461042b5780635fb8bcd51461046457806361bc221a1461049357600080fd5b8063357113461461038357806342842e0e146103985780634d96f2c2146103b85780634f6ccce7146103cb57600080fd5b806318160ddd116101e257806318160ddd146102c557806323b872dd146102e45780632812a3d2146103045780632a55205a146103245780632f745c591461036357600080fd5b806301ffc9a71461021457806306fdde0314610249578063081812fc1461026b578063095ea7b3146102a3575b600080fd5b34801561022057600080fd5b5061023461022f366004611e90565b6106db565b60405190151581526020015b60405180910390f35b34801561025557600080fd5b5061025e6106ec565b6040516102409190611efa565b34801561027757600080fd5b5061028b610286366004611f0d565b61077e565b6040516001600160a01b039091168152602001610240565b3480156102af57600080fd5b506102c36102be366004611f3b565b6107a5565b005b3480156102d157600080fd5b506010545b604051908152602001610240565b3480156102f057600080fd5b506102c36102ff366004611f67565b6108bf565b34801561031057600080fd5b506102c361031f366004611fa8565b6108f0565b34801561033057600080fd5b5061034461033f366004611fc5565b610974565b604080516001600160a01b039093168352602083019190915201610240565b34801561036f57600080fd5b506102d661037e366004611f3b565b610a20565b34801561038f57600080fd5b5061028b610ab6565b3480156103a457600080fd5b506102c36103b3366004611f67565b610b29565b6102d66103c6366004612093565b610b44565b3480156103d757600080fd5b506102d66103e6366004611f0d565b610c7c565b3480156103f757600080fd5b506102c361040636600461211d565b610d0f565b34801561041757600080fd5b506102c361042636600461211d565b610d27565b34801561043757600080fd5b5061028b610446366004611f0d565b6000908152600760205260409020600101546001600160a01b031690565b34801561047057600080fd5b5061048461047f366004611f0d565b610d3b565b60405161024093929190612152565b34801561049f57600080fd5b506102d660065481565b3480156104b557600080fd5b5061028b6104c4366004611f0d565b610df0565b3480156104d557600080fd5b5061025e610e25565b3480156104ea57600080fd5b506102d66104f9366004611fa8565b610eb3565b34801561050a57600080fd5b506102c3610f39565b34801561051f57600080fd5b5061025e610f4d565b34801561053457600080fd5b506000546001600160a01b031661028b565b34801561055257600080fd5b5060045461028b906001600160a01b031681565b34801561057257600080fd5b5061025e610f5c565b34801561058757600080fd5b506102c3610596366004612185565b610f6b565b3480156105a757600080fd5b506102c36105b63660046121f7565b610f80565b3480156105c757600080fd5b5060015461028b906001600160a01b031681565b3480156105e757600080fd5b506102c36105f6366004612235565b610f8b565b34801561060757600080fd5b5061025e610616366004611f0d565b610fc3565b34801561062757600080fd5b5061063b610636366004611fa8565b61109f565b60405161024091906122b5565b34801561065457600080fd5b506102d66111b4565b34801561066957600080fd5b5061025e61121f565b34801561067e57600080fd5b5061023461068d3660046122f9565b6001600160a01b039182166000908152600d6020908152604080832093909416825291909152205460ff1690565b3480156106c757600080fd5b506102c36106d6366004611fa8565b61122e565b60006106e6826112a7565b92915050565b6060600880546106fb90612327565b80601f016020809104026020016040519081016040528092919081815260200182805461072790612327565b80156107745780601f1061074957610100808354040283529160200191610774565b820191906000526020600020905b81548152906001019060200180831161075757829003601f168201915b5050505050905090565b6000610789826112cc565b506000908152600c60205260409020546001600160a01b031690565b60006107b082610df0565b9050806001600160a01b0316836001600160a01b0316036108225760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061083e575061083e813361068d565b6108b05760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610819565b6108ba8383611300565b505050565b6108c9338261136e565b6108e55760405162461bcd60e51b815260040161081990612361565b6108ba8383836113ec565b6108f861155d565b6004546001600160a01b039081169082160361091357600080fd5b600480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f9aaef5934caac7bf8ee7de13d1a1e98122180cb78e64abeae728ad559df64a66910160405180910390a15050565b60008281526013602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916109e95750604080518082019091526012546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610a08906001600160601b0316876123c4565b610a1291906123db565b915196919550909350505050565b6000610a2b83610eb3565b8210610a8d5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610819565b506001600160a01b03919091166000908152600e60209081526040808320938352929052205490565b60015460408051631ab889a360e11b815290516000926001600160a01b03169163357113469160048083019260209291908290030181865afa158015610b00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2491906123fd565b905090565b6108ba83838360405180602001604052806000815250610f8b565b600080600660008154610b569061241a565b9182905550604080516060810182528581523360208083019182528284018a8152600086815260079092529390208251815590516001820180546001600160a01b0319166001600160a01b039092169190911790559151929350918291906002820190610bc39082612481565b50905050610bd133836115b7565b6000828152601460205260409020610be98882612481565b506001600160601b03851615610c0457610c04823387611750565b60048054604051630f384cd960e01b8152918201869052306024830152604482018490526001600160a01b031690630f384cd99034906064016000604051808303818588803b158015610c5657600080fd5b505af1158015610c6a573d6000803e3d6000fd5b5094955050505050505b949350505050565b6000610c8760105490565b8210610cea5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610819565b60108281548110610cfd57610cfd612541565b90600052602060002001549050919050565b610d1761155d565b6005610d238282612481565b5050565b610d2f61155d565b6003610d238282612481565b60076020526000908152604090208054600182015460028301805492936001600160a01b0390921692610d6d90612327565b80601f0160208091040260200160405190810160405280929190818152602001828054610d9990612327565b8015610de65780601f10610dbb57610100808354040283529160200191610de6565b820191906000526020600020905b815481529060010190602001808311610dc957829003601f168201915b5050505050905083565b6000818152600a60205260408120546001600160a01b0316806106e65760405162461bcd60e51b815260040161081990612557565b60058054610e3290612327565b80601f0160208091040260200160405190810160405280929190818152602001828054610e5e90612327565b8015610eab5780601f10610e8057610100808354040283529160200191610eab565b820191906000526020600020905b815481529060010190602001808311610e8e57829003601f168201915b505050505081565b60006001600160a01b038216610f1d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610819565b506001600160a01b03166000908152600b602052604090205490565b610f4161155d565b610f4b600061185e565b565b6060600280546106fb90612327565b6060600980546106fb90612327565b610f7361155d565b60026108ba82848361258e565b610d233383836118ae565b610f95338361136e565b610fb15760405162461bcd60e51b815260040161081990612361565b610fbd8484848461197c565b50505050565b6000818152601460205260409020805460609190610fe090612327565b90506000036110015760405162461bcd60e51b815260040161081990612557565b6000828152601460205260409020805461101a90612327565b80601f016020809104026020016040519081016040528092919081815260200182805461104690612327565b80156110935780601f1061106857610100808354040283529160200191611093565b820191906000526020600020905b81548152906001019060200180831161107657829003601f168201915b50505050509050919050565b6060600060015b60065481116110f3576000818152600760205260409020600101546001600160a01b038086169116036110e157816110dd8161241a565b9250505b806110eb8161241a565b9150506110a6565b5060008167ffffffffffffffff81111561110f5761110f611fe7565b604051908082528060200260200182016040528015611138578160200160208202803683370190505b509050600060015b60065481116111aa576000818152600760205260409020600101546001600160a01b03808816911603611198578083836111798161241a565b94508151811061118b5761118b612541565b6020026020010181815250505b806111a28161241a565b915050611140565b5090949350505050565b60006111be610ab6565b6001600160a01b031663428c090b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111fb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b24919061264e565b6060600380546106fb90612327565b61123661155d565b6001600160a01b03811661129b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610819565b6112a48161185e565b50565b60006001600160e01b0319821663152a902d60e11b14806106e657506106e6826119af565b6000818152600a60205260409020546001600160a01b03166112a45760405162461bcd60e51b815260040161081990612557565b6000818152600c6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061133582610df0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061137a83610df0565b9050806001600160a01b0316846001600160a01b031614806113c157506001600160a01b038082166000908152600d602090815260408083209388168352929052205460ff165b80610c745750836001600160a01b03166113da8461077e565b6001600160a01b031614949350505050565b826001600160a01b03166113ff82610df0565b6001600160a01b0316146114255760405162461bcd60e51b815260040161081990612667565b6001600160a01b0382166114875760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610819565b61149483838360016119d4565b826001600160a01b03166114a782610df0565b6001600160a01b0316146114cd5760405162461bcd60e51b815260040161081990612667565b6000818152600c6020908152604080832080546001600160a01b03199081169091556001600160a01b03878116808652600b8552838620805460001901905590871680865283862080546001019055868652600a90945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000546001600160a01b03163314610f4b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610819565b6001600160a01b03821661160d5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610819565b6000818152600a60205260409020546001600160a01b0316156116725760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610819565b6116806000838360016119d4565b6000818152600a60205260409020546001600160a01b0316156116e55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610819565b6001600160a01b0382166000818152600b6020908152604080832080546001019055848352600a90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6127106001600160601b03821611156117be5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610819565b6001600160a01b0382166118145760405162461bcd60e51b815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152606401610819565b6040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182526000968752601390529190942093519051909116600160a01b029116179055565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b816001600160a01b0316836001600160a01b03160361190f5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610819565b6001600160a01b038381166000818152600d6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6119878484846113ec565b61199384848484611b14565b610fbd5760405162461bcd60e51b8152600401610819906126ac565b60006001600160e01b0319821663780e9d6360e01b14806106e657506106e682611c12565b6119e084848484611c62565b6001811115611a4f5760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610819565b816001600160a01b038516611aab57611aa681601080546000838152601160205260408120829055600182018355919091527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6720155565b611ace565b836001600160a01b0316856001600160a01b031614611ace57611ace8582611cea565b6001600160a01b038416611aea57611ae581611d87565b611b0d565b846001600160a01b0316846001600160a01b031614611b0d57611b0d8482611e36565b5050505050565b60006001600160a01b0384163b15611c0a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611b589033908990889088906004016126fe565b6020604051808303816000875af1925050508015611b93575060408051601f3d908101601f19168201909252611b909181019061273b565b60015b611bf0573d808015611bc1576040519150601f19603f3d011682016040523d82523d6000602084013e611bc6565b606091505b508051600003611be85760405162461bcd60e51b8152600401610819906126ac565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610c74565b506001610c74565b60006001600160e01b031982166380ac58cd60e01b1480611c4357506001600160e01b03198216635b5e139f60e01b145b806106e657506301ffc9a760e01b6001600160e01b03198316146106e6565b6001811115610fbd576001600160a01b03841615611ca8576001600160a01b0384166000908152600b602052604081208054839290611ca2908490612758565b90915550505b6001600160a01b03831615610fbd576001600160a01b0383166000908152600b602052604081208054839290611cdf90849061276b565b909155505050505050565b60006001611cf784610eb3565b611d019190612758565b6000838152600f6020526040902054909150808214611d54576001600160a01b0384166000908152600e602090815260408083208584528252808320548484528184208190558352600f90915290208190555b506000918252600f602090815260408084208490556001600160a01b039094168352600e81528383209183525290812055565b601054600090611d9990600190612758565b60008381526011602052604081205460108054939450909284908110611dc157611dc1612541565b906000526020600020015490508060108381548110611de257611de2612541565b6000918252602080832090910192909255828152601190915260408082208490558582528120556010805480611e1a57611e1a61277e565b6001900381819060005260206000200160009055905550505050565b6000611e4183610eb3565b6001600160a01b039093166000908152600e602090815260408083208684528252808320859055938252600f9052919091209190915550565b6001600160e01b0319811681146112a457600080fd5b600060208284031215611ea257600080fd5b8135611ead81611e7a565b9392505050565b6000815180845260005b81811015611eda57602081850181015186830182015201611ebe565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000611ead6020830184611eb4565b600060208284031215611f1f57600080fd5b5035919050565b6001600160a01b03811681146112a457600080fd5b60008060408385031215611f4e57600080fd5b8235611f5981611f26565b946020939093013593505050565b600080600060608486031215611f7c57600080fd5b8335611f8781611f26565b92506020840135611f9781611f26565b929592945050506040919091013590565b600060208284031215611fba57600080fd5b8135611ead81611f26565b60008060408385031215611fd857600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff8084111561201857612018611fe7565b604051601f8501601f19908116603f0116810190828211818310171561204057612040611fe7565b8160405280935085815286868601111561205957600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261208457600080fd5b611ead83833560208501611ffd565b600080600080608085870312156120a957600080fd5b843567ffffffffffffffff808211156120c157600080fd5b6120cd88838901612073565b955060208701359150808211156120e357600080fd5b506120f087828801612073565b93505060408501356001600160601b038116811461210d57600080fd5b9396929550929360600135925050565b60006020828403121561212f57600080fd5b813567ffffffffffffffff81111561214657600080fd5b610c7484828501612073565b8381526001600160a01b038316602082015260606040820181905260009061217c90830184611eb4565b95945050505050565b6000806020838503121561219857600080fd5b823567ffffffffffffffff808211156121b057600080fd5b818501915085601f8301126121c457600080fd5b8135818111156121d357600080fd5b8660208285010111156121e557600080fd5b60209290920196919550909350505050565b6000806040838503121561220a57600080fd5b823561221581611f26565b91506020830135801515811461222a57600080fd5b809150509250929050565b6000806000806080858703121561224b57600080fd5b843561225681611f26565b9350602085013561226681611f26565b925060408501359150606085013567ffffffffffffffff81111561228957600080fd5b8501601f8101871361229a57600080fd5b6122a987823560208401611ffd565b91505092959194509250565b6020808252825182820181905260009190848201906040850190845b818110156122ed578351835292840192918401916001016122d1565b50909695505050505050565b6000806040838503121561230c57600080fd5b823561231781611f26565b9150602083013561222a81611f26565b600181811c9082168061233b57607f821691505b60208210810361235b57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176106e6576106e66123ae565b6000826123f857634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561240f57600080fd5b8151611ead81611f26565b60006001820161242c5761242c6123ae565b5060010190565b601f8211156108ba57600081815260208120601f850160051c8101602086101561245a5750805b601f850160051c820191505b8181101561247957828155600101612466565b505050505050565b815167ffffffffffffffff81111561249b5761249b611fe7565b6124af816124a98454612327565b84612433565b602080601f8311600181146124e457600084156124cc5750858301515b600019600386901b1c1916600185901b178555612479565b600085815260208120601f198616915b82811015612513578886015182559484019460019091019084016124f4565b50858210156125315787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b60208082526018908201527f4552433732313a20696e76616c696420746f6b656e2049440000000000000000604082015260600190565b67ffffffffffffffff8311156125a6576125a6611fe7565b6125ba836125b48354612327565b83612433565b6000601f8411600181146125ee57600085156125d65750838201355b600019600387901b1c1916600186901b178355611b0d565b600083815260209020601f19861690835b8281101561261f57868501358255602094850194600190920191016125ff565b508682101561263c5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60006020828403121561266057600080fd5b5051919050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061273190830184611eb4565b9695505050505050565b60006020828403121561274d57600080fd5b8151611ead81611e7a565b818103818111156106e6576106e66123ae565b808201808211156106e6576106e66123ae565b634e487b7160e01b600052603160045260246000fdfea26469706673582212202853fabeea88e616e7241fec8e8f4c7120757a44e7cc32b4187844aaa88f98f264736f6c63430008110033", diff --git a/src/contract/VWBLMetaTx.json b/src/contract/VWBLMetaTx.json index 9eff5e21..c997c933 100644 --- a/src/contract/VWBLMetaTx.json +++ b/src/contract/VWBLMetaTx.json @@ -1,5 +1,29 @@ { "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "revoker", + "type": "address" + } + ], + "name": "revokeViewPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -760,6 +784,54 @@ ], "stateMutability": "pure", "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "grantee", + "type": "address" + } + ], + "name": "grantViewPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "checkViewPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" } ] } \ No newline at end of file diff --git a/src/contract/VWBLMetaTxSupportIPFS.json b/src/contract/VWBLMetaTxSupportIPFS.json index c35b7e5b..c7d3f87c 100644 --- a/src/contract/VWBLMetaTxSupportIPFS.json +++ b/src/contract/VWBLMetaTxSupportIPFS.json @@ -1,5 +1,29 @@ { "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "revoker", + "type": "address" + } + ], + "name": "revokeViewPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -765,6 +789,54 @@ ], "stateMutability": "pure", "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "grantee", + "type": "address" + } + ], + "name": "grantViewPermission", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "checkViewPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" } ] } \ No newline at end of file diff --git a/src/util/biconomyHelper.ts b/src/util/biconomyHelper.ts index 2d5a3bb7..3f88d047 100644 --- a/src/util/biconomyHelper.ts +++ b/src/util/biconomyHelper.ts @@ -1,3 +1,4 @@ +import * as abi from "ethereumjs-abi"; import { ethers } from "ethers"; const biconomyForwarderDomainData = { @@ -89,3 +90,22 @@ export const getDomainSeparator = (forwarderAddress: string, chainId: number) => ); return domainSeparator; }; + +export const getDataToSignForPersonalSign = (request: TxParam) => { + const hashToSign = abi.soliditySHA3( + ["address", "address", "address", "uint256", "uint256", "uint256", "uint256", "uint256", "bytes32"], + [ + request.from, + request.to, + request.token, + request.txGas, + request.tokenGasPrice, + request.batchId, + request.batchNonce, + request.deadline, + ethers.utils.keccak256(request.data), + ] + ); + + return hashToSign; +}; diff --git a/src/vwbl/base.ts b/src/vwbl/base.ts index 92c1a47c..f0e9fdf7 100644 --- a/src/vwbl/base.ts +++ b/src/vwbl/base.ts @@ -49,7 +49,7 @@ export class VWBLBase { * @remarks * You need to call this method before you send a transaction(eg. mint NFT, decrypt NFT data) */ - protected _sign = async (signer: Web3 | ethers.providers.JsonRpcSigner | ethers.Wallet, targetContract?: string) => { + protected _sign = async (signer: Web3 | ethers.Signer, targetContract?: string) => { //TODO: signerがWeb3 instanceかどうかを判断するロジックを切り出さないといけない signer instanceof Web3では意図した通り動かなかったため const castedSigner = signer as any; // eslint-disable-next-line @@ -67,9 +67,7 @@ export class VWBLBase { console.log("signed"); }; - protected _getAddressBySigner = async ( - signer: Web3 | ethers.providers.JsonRpcSigner | ethers.Wallet - ): Promise => { + protected _getAddressBySigner = async (signer: Web3 | ethers.Signer): Promise => { //TODO: signerがWeb3 instanceかどうかを判断するロジックを切り出さないといけない signer instanceof Web3では意図した通り動かなかったため const castedSigner = signer as any; // eslint-disable-next-line diff --git a/src/vwbl/blockchain/Sign.ts b/src/vwbl/blockchain/Sign.ts index 231a4f1f..723d34b7 100644 --- a/src/vwbl/blockchain/Sign.ts +++ b/src/vwbl/blockchain/Sign.ts @@ -9,10 +9,7 @@ const isEthersSigner = (signer: IEthersSigner): signer is IEthersSigner => { return signer.signMessage !== undefined; }; -export const signToProtocol = async ( - signer: Web3 | ethers.providers.JsonRpcSigner | ethers.Wallet, - signMessage: string -) => { +export const signToProtocol = async (signer: Web3 | ethers.Signer, signMessage: string) => { if (isEthersSigner(signer as IEthersSigner)) { return await (signer as IEthersSigner).signMessage(signMessage); } else { diff --git a/src/vwbl/blockchain/erc1155/VWBLProtocolEthers.ts b/src/vwbl/blockchain/erc1155/VWBLProtocolEthers.ts index 0b5fb49f..ef391b15 100644 --- a/src/vwbl/blockchain/erc1155/VWBLProtocolEthers.ts +++ b/src/vwbl/blockchain/erc1155/VWBLProtocolEthers.ts @@ -7,14 +7,14 @@ import { GasSettings } from "../../types"; export class VWBLERC1155EthersContract { private ethersProvider: ethers.providers.BaseProvider; - private ethersSigner: ethers.providers.JsonRpcSigner | ethers.Wallet; + private ethersSigner: ethers.Signer; private contract: ethers.Contract; constructor( address: string, isIpfs: boolean, ethersProvider: ethers.providers.BaseProvider, - ethersSigner: ethers.providers.JsonRpcSigner | ethers.Wallet + ethersSigner: ethers.Signer ) { this.ethersProvider = ethersProvider; this.ethersSigner = ethersSigner; diff --git a/src/vwbl/blockchain/erc6150/VWBLMetaTxProtocol.ts b/src/vwbl/blockchain/erc6150/VWBLMetaTxProtocol.ts new file mode 100644 index 00000000..890b0a41 --- /dev/null +++ b/src/vwbl/blockchain/erc6150/VWBLMetaTxProtocol.ts @@ -0,0 +1,105 @@ +import { ethers } from "ethers"; + +import vwblERC6150 from "../../../contract/VWBLERC6150ERC2981.json"; +import vwblERC6150Ipfs from "../../../contract/VWBLERC6150ERC2981ForMetadata.json"; +import { GrantViewPermissionMetaTxParam, MintForIPFSMetaTxParam, MintMetaTxParam } from "../../types"; +import { VWBLNFTMetaTx } from "../erc721/VWBLMetaTxProtocol"; +import { parseToTokenId } from "../erc721/VWBLProtocolEthers"; + +export class VWBLERC6150MetaTxEthers extends VWBLNFTMetaTx { + private erc6150Address: string; + + constructor( + biconomyAPIKey: string, + walletProvider: ethers.providers.Web3Provider | ethers.Wallet, + address: string, + forwarderAddress: string + ) { + super(biconomyAPIKey, walletProvider, address, forwarderAddress); + this.erc6150Address = address; + } + + override async mintToken(mintParam: MintMetaTxParam): Promise { + const myAddress = await this.ethersSigner.getAddress(); + const vwblMetaTxContract = new ethers.Contract(this.erc6150Address, vwblERC6150.abi, this.ethersSigner); + const { data } = await vwblMetaTxContract.populateTransaction.mint( + mintParam.decryptUrl, + mintParam.parentId, + mintParam.feeNumerator, + mintParam.documentId + ); + const chainId = await this.ethersSigner.getChainId(); + const { txParam, sig, domainSeparator, signatureType } = await this.constructMetaTx(myAddress, data!, chainId); + console.log("transaction start"); + const receipt = await this.sendTransaction( + txParam, + sig, + myAddress, + domainSeparator, + mintParam.mintApiId, + signatureType + ); + console.log("transaction end"); + const tokenId = parseToTokenId(receipt); + return tokenId; + } + + override async mintTokenForIPFS(mintForIPFSParam: MintForIPFSMetaTxParam): Promise { + const myAddress = await this.ethersSigner.getAddress(); + const vwblMetaTxContract = new ethers.Contract(this.erc6150Address, vwblERC6150Ipfs.abi, this.ethersSigner); + const { data } = await vwblMetaTxContract.populateTransaction.mint( + mintForIPFSParam.metadataUrl, + mintForIPFSParam.parentId, + mintForIPFSParam.decryptUrl, + mintForIPFSParam.feeNumerator, + mintForIPFSParam.documentId + ); + const chainId = await this.ethersSigner.getChainId(); + const { txParam, sig, domainSeparator, signatureType } = await this.constructMetaTx(myAddress, data!, chainId); + console.log("transaction start"); + const receipt = await this.sendTransaction( + txParam, + sig, + myAddress, + domainSeparator, + mintForIPFSParam.mintApiId, + signatureType + ); + console.log("transaction end"); + const tokenId = parseToTokenId(receipt); + return tokenId; + } + + override async grantViewPermission(grantParam: GrantViewPermissionMetaTxParam): Promise { + const myAddress = await this.ethersSigner.getAddress(); + const vwblMetaTxContract = new ethers.Contract(this.erc6150Address, vwblERC6150Ipfs.abi, this.ethersSigner); + const { data } = await vwblMetaTxContract.populateTransaction.grantViewPermission( + grantParam.tokenId, + grantParam.grantee, + grantParam.toDir + ); + const chainId = await this.ethersSigner.getChainId(); + const { txParam, sig, domainSeparator, signatureType } = await this.constructMetaTx(myAddress, data!, chainId); + console.log("transaction start"); + await this.sendTransaction( + txParam, + sig, + myAddress, + domainSeparator, + grantParam.grantViewPermissionApiId, + signatureType + ); + console.log("transaction end"); + } + + async revokeDirPermission(tokenId: number, revoker: string, revokeViewPermisionApiId: string): Promise { + const myAddress = await this.ethersSigner.getAddress(); + const vwblMetaTxContract = new ethers.Contract(this.erc6150Address, vwblERC6150Ipfs.abi, this.ethersSigner); + const { data } = await vwblMetaTxContract.populateTransaction.revokeDirPermission(tokenId, revoker); + const chainId = await this.ethersSigner.getChainId(); + const { txParam, sig, domainSeparator, signatureType } = await this.constructMetaTx(myAddress, data!, chainId); + console.log("transaction start"); + await this.sendTransaction(txParam, sig, myAddress, domainSeparator, revokeViewPermisionApiId, signatureType); + console.log("transaction end"); + } +} diff --git a/src/vwbl/blockchain/erc6150/VWBLProtocol.ts b/src/vwbl/blockchain/erc6150/VWBLProtocol.ts new file mode 100644 index 00000000..b83b1688 --- /dev/null +++ b/src/vwbl/blockchain/erc6150/VWBLProtocol.ts @@ -0,0 +1,155 @@ +import { Web3 } from "web3"; + +import vwblERC6150 from "../../../contract/VWBLERC6150ERC2981.json"; +import vwblERC6150IPFS from "../../../contract/VWBLERC6150ERC2981ForMetadata.json"; +import { getFeeSettingsBasedOnEnvironment } from "../../../util/transactionHelper"; +import { GasSettings, GrantViewPermissionTxParam, MintForIPFSTxParam, MintTxParam } from "../../types"; +import { VWBLNFT } from "../erc721/VWBLProtocol"; + +export class VWBLERC6150Web3 extends VWBLNFT { + private erc6150Contract: any; // eslint-disable-line + + constructor(web3: Web3, address: string, isIpfs: boolean) { + super(web3, address, isIpfs); + this.erc6150Contract = isIpfs + ? new web3.eth.Contract(vwblERC6150IPFS.abi, address) + : new web3.eth.Contract(vwblERC6150.abi, address); + } + + override async mintToken(mintParam: MintTxParam): Promise { + const myAddress = (await this.web3.eth.getAccounts())[0]; + const fee = await this.getFee(); + let txSettings: unknown; + if (mintParam.gasSettings?.gasPrice) { + const gas = await this.erc6150Contract.methods + .mint(mintParam.decryptUrl, mintParam.parentId, mintParam.feeNumerator, mintParam.documentId) + .estimateGas({ from: myAddress, value: fee }); + txSettings = { + from: myAddress, + value: fee, + gasPrice: mintParam.gasSettings?.gasPrice, + gas, + }; + } else { + const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = + getFeeSettingsBasedOnEnvironment( + mintParam.gasSettings?.maxPriorityFeePerGas, + mintParam.gasSettings?.maxFeePerGas + ); + txSettings = { + from: myAddress, + value: fee, + maxPriorityFeePerGas: _maxPriorityFeePerGas, + maxFeePerGas: _maxFeePerGas, + }; + } + console.log("transaction start"); + const receipt = await this.erc6150Contract.methods + .mint(mintParam.decryptUrl, mintParam.parentId, mintParam.feeNumerator, mintParam.documentId) + .send(txSettings); + console.log("transaction end"); + const tokenId: number = receipt.events.Transfer.returnValues.tokenId; + return tokenId; + } + + override async mintTokenForIPFS(mintForIPFSParam: MintForIPFSTxParam): Promise { + const myAddress = (await this.web3.eth.getAccounts())[0]; + const fee = await this.getFee(); + let txSettings: unknown; + if (mintForIPFSParam.gasSettings?.gasPrice) { + const gas = await this.erc6150Contract.methods + .mint( + mintForIPFSParam.metadataUrl, + mintForIPFSParam.decryptUrl, + mintForIPFSParam.parentId, + mintForIPFSParam.feeNumerator, + mintForIPFSParam.documentId + ) + .estimateGas({ from: myAddress, value: fee }); + txSettings = { + from: myAddress, + value: fee, + gasPrice: mintForIPFSParam.gasSettings?.gasPrice, + gas, + }; + } else { + const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = + getFeeSettingsBasedOnEnvironment( + mintForIPFSParam.gasSettings?.maxPriorityFeePerGas, + mintForIPFSParam.gasSettings?.maxFeePerGas + ); + txSettings = { + from: myAddress, + value: fee, + maxPriorityFeePerGas: _maxPriorityFeePerGas, + maxFeePerGas: _maxFeePerGas, + }; + } + console.log("transaction start"); + const receipt = await this.erc6150Contract.methods + .mint( + mintForIPFSParam.metadataUrl, + mintForIPFSParam.decryptUrl, + mintForIPFSParam.parentId, + mintForIPFSParam.feeNumerator, + mintForIPFSParam.documentId + ) + .send(txSettings); + console.log("transaction end"); + const tokenId: number = receipt.events.Transfer.returnValues.tokenId; + return tokenId; + } + + override async grantViewPermission(grantParam: GrantViewPermissionTxParam): Promise { + const myAddress = (await this.web3.eth.getAccounts())[0]; + let txSettings: unknown; + if (grantParam.gasSettings?.gasPrice) { + const gas = await this.erc6150Contract.methods + .grantViewPermission(grantParam.tokenId, grantParam.grantee, grantParam.toDir) + .estimateGas({ from: myAddress }); + txSettings = { + from: myAddress, + gasPrice: grantParam.gasSettings?.gasPrice, + gas, + }; + } else { + const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = + getFeeSettingsBasedOnEnvironment( + grantParam.gasSettings?.maxPriorityFeePerGas, + grantParam.gasSettings?.maxFeePerGas + ); + txSettings = { + from: myAddress, + maxPriorityFeePerGas: _maxPriorityFeePerGas, + maxFeePerGas: _maxFeePerGas, + }; + } + await this.erc6150Contract.methods + .grantViewPermission(grantParam.tokenId, grantParam.grantee, grantParam.toDir) + .send(txSettings); + } + + async revokeDirPermission(tokenId: number, revoker: string, gasSettings?: GasSettings): Promise { + const myAddress = (await this.web3.eth.getAccounts())[0]; + let txSettings: unknown; + if (gasSettings?.gasPrice) { + const gas = await this.erc6150Contract.methods + .revokeDirPermission(tokenId, revoker) + .estimateGas({ from: myAddress }); + txSettings = { + from: myAddress, + gasPrice: gasSettings?.gasPrice, + gas, + }; + } else { + const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = + getFeeSettingsBasedOnEnvironment(gasSettings?.maxPriorityFeePerGas, gasSettings?.maxFeePerGas); + txSettings = { + from: myAddress, + maxPriorityFeePerGas: _maxPriorityFeePerGas, + maxFeePerGas: _maxFeePerGas, + }; + } + await this.erc6150Contract.methods.revokeDirPermission(tokenId, revoker).send(txSettings); + } +} diff --git a/src/vwbl/blockchain/erc6150/VWBLProtocolEthers.ts b/src/vwbl/blockchain/erc6150/VWBLProtocolEthers.ts new file mode 100644 index 00000000..01cffd6c --- /dev/null +++ b/src/vwbl/blockchain/erc6150/VWBLProtocolEthers.ts @@ -0,0 +1,136 @@ +import { ethers } from "ethers"; + +import vwblERC6150 from "../../../contract/VWBLERC6150ERC2981.json"; +import vwblERC6150IPFS from "../../../contract/VWBLERC6150ERC2981ForMetadata.json"; +import { getFeeSettingsBasedOnEnvironment } from "../../../util/transactionHelper"; +import { GasSettings, GrantViewPermissionTxParam, MintForIPFSTxParam, MintTxParam } from "../../types"; +import { parseToTokenId, VWBLNFTEthers } from "../erc721/VWBLProtocolEthers"; + +export class VWBLERC6150Ethers extends VWBLNFTEthers { + private erc6150Contract: ethers.Contract; + + constructor( + address: string, + isIpfs: boolean, + ethersProvider: ethers.providers.BaseProvider, + ethersSigner: ethers.Signer + ) { + super(address, isIpfs, ethersProvider, ethersSigner); + this.erc6150Contract = isIpfs + ? new ethers.Contract(address, vwblERC6150IPFS.abi, ethersSigner) + : new ethers.Contract(address, vwblERC6150.abi, ethersSigner); + } + + override async mintToken(mintParam: MintTxParam): Promise { + const fee = await this.getFee(); + let txSettings: unknown; + if (mintParam.gasSettings?.gasPrice) { + txSettings = { + value: fee, + gasPrice: mintParam.gasSettings?.gasPrice, + }; + } else { + const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = + getFeeSettingsBasedOnEnvironment( + mintParam.gasSettings?.maxPriorityFeePerGas, + mintParam.gasSettings?.maxFeePerGas + ); + txSettings = { + value: fee, + maxPriorityFeePerGas: _maxPriorityFeePerGas, + maxFeePerGas: _maxFeePerGas, + }; + } + console.log("transaction start"); + const tx = await this.erc6150Contract.mint( + mintParam.decryptUrl, + mintParam.parentId, + mintParam.feeNumerator, + mintParam.documentId, + txSettings + ); + const receipt = await this.ethersProvider.waitForTransaction(tx.hash); + console.log("transaction end"); + const tokenId = parseToTokenId(receipt); + return tokenId; + } + + override async mintTokenForIPFS(mintForIPFSParam: MintForIPFSTxParam): Promise { + const fee = await this.getFee(); + let txSettings: unknown; + if (mintForIPFSParam.gasSettings?.gasPrice) { + txSettings = { + value: fee, + gasPrice: mintForIPFSParam.gasSettings?.gasPrice, + }; + } else { + const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = + getFeeSettingsBasedOnEnvironment( + mintForIPFSParam.gasSettings?.maxPriorityFeePerGas, + mintForIPFSParam.gasSettings?.maxFeePerGas + ); + txSettings = { + value: fee, + maxPriorityFeePerGas: _maxPriorityFeePerGas, + maxFeePerGas: _maxFeePerGas, + }; + } + console.log("transaction start"); + const tx = await this.erc6150Contract.mint( + mintForIPFSParam.metadataUrl, + mintForIPFSParam.decryptUrl, + mintForIPFSParam.parentId, + mintForIPFSParam.feeNumerator, + mintForIPFSParam.documentId, + txSettings + ); + const receipt = await this.ethersProvider.waitForTransaction(tx.hash); + console.log("transaction end"); + const tokenId = parseToTokenId(receipt); + return tokenId; + } + + override async grantViewPermission(grantParam: GrantViewPermissionTxParam): Promise { + let txSettings: unknown; + if (grantParam.gasSettings?.gasPrice) { + txSettings = { + gasPrice: grantParam.gasSettings?.gasPrice, + }; + } else { + const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = + getFeeSettingsBasedOnEnvironment( + grantParam.gasSettings?.maxPriorityFeePerGas, + grantParam.gasSettings?.maxFeePerGas + ); + txSettings = { + maxPriorityFeePerGas: _maxPriorityFeePerGas, + maxFeePerGas: _maxFeePerGas, + }; + } + const tx = await this.erc6150Contract.grantViewPermission( + grantParam.tokenId, + grantParam.grantee, + grantParam.toDir, + txSettings + ); + await this.ethersProvider.waitForTransaction(tx.hash); + } + + async revokeDirPermission(tokenId: number, revoker: string, gasSettings?: GasSettings): Promise { + let txSettings: unknown; + if (gasSettings?.gasPrice) { + txSettings = { + gasPrice: gasSettings?.gasPrice, + }; + } else { + const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = + getFeeSettingsBasedOnEnvironment(gasSettings?.maxPriorityFeePerGas, gasSettings?.maxFeePerGas); + txSettings = { + maxPriorityFeePerGas: _maxPriorityFeePerGas, + maxFeePerGas: _maxFeePerGas, + }; + } + const tx = await this.erc6150Contract.revokeDirPermission(tokenId, revoker, txSettings); + await this.ethersProvider.waitForTransaction(tx.hash); + } +} diff --git a/src/vwbl/blockchain/erc721/VWBLMetaTxProtocol.ts b/src/vwbl/blockchain/erc721/VWBLMetaTxProtocol.ts index 84d1b849..a34f2d41 100644 --- a/src/vwbl/blockchain/erc721/VWBLMetaTxProtocol.ts +++ b/src/vwbl/blockchain/erc721/VWBLMetaTxProtocol.ts @@ -7,71 +7,86 @@ import vwblMetaTxIpfs from "../../../contract/VWBLMetaTxSupportIPFS.json"; import { buildForwardTxRequest, getDataToSignForEIP712, + getDataToSignForPersonalSign, getDomainSeparator, TxParam, } from "../../../util/biconomyHelper"; +import { GrantViewPermissionMetaTxParam, MintForIPFSMetaTxParam, MintMetaTxParam } from "../../types"; export class VWBLNFTMetaTx { - private walletProvider: ethers.providers.Web3Provider; + private walletProvider: ethers.providers.Web3Provider | ethers.Wallet; + protected ethersSigner: ethers.Signer; private nftAddress: string; private forwarderAddress: string; private biconomyAPIKey: string; constructor( biconomyAPIKey: string, - walletProvider: ethers.providers.Web3Provider, + walletProvider: ethers.providers.Web3Provider | ethers.Wallet, nftAddress: string, forwarderAddress: string ) { this.biconomyAPIKey = biconomyAPIKey; this.walletProvider = walletProvider; + this.ethersSigner = isWeb3Provider(walletProvider as IWeb3Provider) + ? (walletProvider as IWeb3Provider).getSigner() + : (walletProvider as ethers.Wallet); this.nftAddress = nftAddress; this.forwarderAddress = forwarderAddress; } - async mintToken(decryptUrl: string, feeNumerator: number, documentId: string, mintApiId: string): Promise { - const walletSigner = this.walletProvider.getSigner(); - const myAddress = await walletSigner.getAddress(); - const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTx.abi, walletSigner); - const { data } = await vwblMetaTxContract.populateTransaction.mint(decryptUrl, feeNumerator, documentId); - const chainId = await walletSigner.getChainId(); - const { txParam, sig, domainSeparator } = await this.constructMetaTx(myAddress, data!, chainId); + async mintToken(mintParam: MintMetaTxParam): Promise { + const myAddress = await this.ethersSigner.getAddress(); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTx.abi, this.ethersSigner); + const { data } = await vwblMetaTxContract.populateTransaction.mint( + mintParam.decryptUrl, + mintParam.feeNumerator, + mintParam.documentId + ); + const chainId = await this.ethersSigner.getChainId(); + const { txParam, sig, domainSeparator, signatureType } = await this.constructMetaTx(myAddress, data!, chainId); console.log("transaction start"); - const receipt = await this.sendTransaction(txParam, sig, myAddress, domainSeparator, mintApiId, "EIP712_SIGN"); + const receipt = await this.sendTransaction( + txParam, + sig, + myAddress, + domainSeparator, + mintParam.mintApiId, + signatureType + ); console.log("transaction end"); const tokenId = parseToTokenId(receipt); return tokenId; } - async mintTokenForIPFS( - metadataUrl: string, - decryptUrl: string, - feeNumerator: number, - documentId: string, - mintApiId: string - ): Promise { - const walletSigner = this.walletProvider.getSigner(); - const myAddress = await walletSigner.getAddress(); - const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, walletSigner); + async mintTokenForIPFS(mintForIPFSParam: MintForIPFSMetaTxParam): Promise { + const myAddress = await this.ethersSigner.getAddress(); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); const { data } = await vwblMetaTxContract.populateTransaction.mint( - metadataUrl, - decryptUrl, - feeNumerator, - documentId + mintForIPFSParam.metadataUrl, + mintForIPFSParam.decryptUrl, + mintForIPFSParam.feeNumerator, + mintForIPFSParam.documentId ); - const chainId = await walletSigner.getChainId(); - const { txParam, sig, domainSeparator } = await this.constructMetaTx(myAddress, data!, chainId); + const chainId = await this.ethersSigner.getChainId(); + const { txParam, sig, domainSeparator, signatureType } = await this.constructMetaTx(myAddress, data!, chainId); console.log("transaction start"); - const receipt = await this.sendTransaction(txParam, sig, myAddress, domainSeparator, mintApiId, "EIP712_SIGN"); + const receipt = await this.sendTransaction( + txParam, + sig, + myAddress, + domainSeparator, + mintForIPFSParam.mintApiId, + signatureType + ); console.log("transaction end"); const tokenId = parseToTokenId(receipt); return tokenId; } async getOwnTokenIds() { - const walletSigner = this.walletProvider.getSigner(); - const myAddress = await walletSigner.getAddress(); - const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, walletSigner); + const myAddress = await this.ethersSigner.getAddress(); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); const balance = await vwblMetaTxContract.callStatic.balanceOf(myAddress); return await Promise.all( range(Number.parseInt(balance)).map(async (i) => { @@ -82,128 +97,133 @@ export class VWBLNFTMetaTx { } async getTokenByMinter(address: string) { - const vwblMetaTxContract = new ethers.Contract( - this.nftAddress, - vwblMetaTxIpfs.abi, - this.walletProvider.getSigner() - ); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); return await vwblMetaTxContract.callStatic.getTokenByMinter(address); } async getMetadataUrl(tokenId: number) { - const vwblMetaTxContract = new ethers.Contract( - this.nftAddress, - vwblMetaTxIpfs.abi, - this.walletProvider.getSigner() - ); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); return await vwblMetaTxContract.callStatic.tokenURI(tokenId); } async getOwner(tokenId: number) { - const vwblMetaTxContract = new ethers.Contract( - this.nftAddress, - vwblMetaTxIpfs.abi, - this.walletProvider.getSigner() - ); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); return await vwblMetaTxContract.callStatic.ownerOf(tokenId); } async getMinter(tokenId: number) { - const vwblMetaTxContract = new ethers.Contract( - this.nftAddress, - vwblMetaTxIpfs.abi, - this.walletProvider.getSigner() - ); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); return await vwblMetaTxContract.callStatic.getMinter(tokenId); } + async checkViewPermission(tokenId: number, user: string) { + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); + return await vwblMetaTxContract.callStatic.checkViewPermission(tokenId, user); + } + async isOwnerOf(tokenId: number) { - const walletSigner = this.walletProvider.getSigner(); - const myAddress = await walletSigner.getAddress(); + const myAddress = await this.ethersSigner.getAddress(); const owner = await this.getOwner(tokenId); return myAddress === owner; } async isMinterOf(tokenId: number) { - const walletSigner = this.walletProvider.getSigner(); - const myAddress = await walletSigner.getAddress(); + const myAddress = await this.ethersSigner.getAddress(); const minter = await this.getMinter(tokenId); return myAddress === minter; } + async isGranteeOf(tokenId: number) { + const myAddress = await this.ethersSigner.getAddress(); + return await this.checkViewPermission(tokenId, myAddress); + } + async getFee() { - const vwblMetaTxContract = new ethers.Contract( - this.nftAddress, - vwblMetaTxIpfs.abi, - this.walletProvider.getSigner() - ); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); return await vwblMetaTxContract.callStatic.getFee(); } async getTokenInfo(tokenId: number) { - const vwblMetaTxContract = new ethers.Contract( - this.nftAddress, - vwblMetaTxIpfs.abi, - this.walletProvider.getSigner() - ); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); return await vwblMetaTxContract.callStatic.tokenIdToTokenInfo(tokenId); } async approve(operator: string, tokenId: number, approveApiId: string): Promise { - const walletSigner = this.walletProvider.getSigner(); - const myAddress = await walletSigner.getAddress(); - const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, walletSigner); + const myAddress = await this.ethersSigner.getAddress(); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); const { data } = await vwblMetaTxContract.populateTransaction.approve(operator, tokenId); - const chainId = await walletSigner.getChainId(); - const { txParam, sig, domainSeparator } = await this.constructMetaTx(myAddress, data!, chainId); + const chainId = await this.ethersSigner.getChainId(); + const { txParam, sig, domainSeparator, signatureType } = await this.constructMetaTx(myAddress, data!, chainId); console.log("transaction start"); - await this.sendTransaction(txParam, sig, myAddress, domainSeparator, approveApiId, "EIP712_SIGN"); + await this.sendTransaction(txParam, sig, myAddress, domainSeparator, approveApiId, signatureType); console.log("transaction end"); } async getApproved(tokenId: number): Promise { - const vwblMetaTxContract = new ethers.Contract( - this.nftAddress, - vwblMetaTxIpfs.abi, - this.walletProvider.getSigner() - ); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); return await vwblMetaTxContract.callStatic.getApproved(tokenId); } async setApprovalForAll(operator: string, setApprovalForAllApiId: string): Promise { - const walletSigner = this.walletProvider.getSigner(); - const myAddress = await walletSigner.getAddress(); - const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, walletSigner); + const myAddress = await this.ethersSigner.getAddress(); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); const { data } = await vwblMetaTxContract.populateTransaction.setApprovalForAll(operator); - const chainId = await walletSigner.getChainId(); - const { txParam, sig, domainSeparator } = await this.constructMetaTx(myAddress, data!, chainId); + const chainId = await this.ethersSigner.getChainId(); + const { txParam, sig, domainSeparator, signatureType } = await this.constructMetaTx(myAddress, data!, chainId); console.log("transaction start"); - await this.sendTransaction(txParam, sig, myAddress, domainSeparator, setApprovalForAllApiId, "EIP712_SIGN"); + await this.sendTransaction(txParam, sig, myAddress, domainSeparator, setApprovalForAllApiId, signatureType); console.log("transaction end"); } async isApprovedForAll(owner: string, operator: string): Promise { - const vwblMetaTxContract = new ethers.Contract( - this.nftAddress, - vwblMetaTxIpfs.abi, - this.walletProvider.getSigner() - ); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); return await vwblMetaTxContract.callStatic.isApprovedForAll(owner, operator); } async safeTransfer(to: string, tokenId: number, safeTransferFromApiId: string): Promise { - const walletSigner = this.walletProvider.getSigner(); - const myAddress = await walletSigner.getAddress(); - const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, walletSigner); + const myAddress = await this.ethersSigner.getAddress(); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); const { data } = await vwblMetaTxContract.populateTransaction.safeTransferFrom(myAddress, to, tokenId); - const chainId = await walletSigner.getChainId(); - const { txParam, sig, domainSeparator } = await this.constructMetaTx(myAddress, data!, chainId); + const chainId = await this.ethersSigner.getChainId(); + const { txParam, sig, domainSeparator, signatureType } = await this.constructMetaTx(myAddress, data!, chainId); + console.log("transaction start"); + await this.sendTransaction(txParam, sig, myAddress, domainSeparator, safeTransferFromApiId, signatureType); + console.log("transaction end"); + } + + async grantViewPermission(grantParam: GrantViewPermissionMetaTxParam): Promise { + const myAddress = await this.ethersSigner.getAddress(); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); + const { data } = await vwblMetaTxContract.populateTransaction.grantViewPermission( + grantParam.tokenId, + grantParam.grantee + ); + const chainId = await this.ethersSigner.getChainId(); + const { txParam, sig, domainSeparator, signatureType } = await this.constructMetaTx(myAddress, data!, chainId); + console.log("transaction start"); + await this.sendTransaction( + txParam, + sig, + myAddress, + domainSeparator, + grantParam.grantViewPermissionApiId, + signatureType + ); + console.log("transaction end"); + } + + async revokeViewPermission(tokenId: number, revoker: string, revokeViewPermissionApiId: string): Promise { + const myAddress = await this.ethersSigner.getAddress(); + const vwblMetaTxContract = new ethers.Contract(this.nftAddress, vwblMetaTxIpfs.abi, this.ethersSigner); + const { data } = await vwblMetaTxContract.populateTransaction.revokeViewPermission(tokenId, revoker); + const chainId = await this.ethersSigner.getChainId(); + const { txParam, sig, domainSeparator, signatureType } = await this.constructMetaTx(myAddress, data!, chainId); console.log("transaction start"); - await this.sendTransaction(txParam, sig, myAddress, domainSeparator, safeTransferFromApiId, "EIP712_SIGN"); + await this.sendTransaction(txParam, sig, myAddress, domainSeparator, revokeViewPermissionApiId, signatureType); console.log("transaction end"); } - private async constructMetaTx(myAddress: string, data: string, chainId: number) { + protected async constructMetaTx(myAddress: string, data: string, chainId: number) { console.log("estimate gas start"); const gasLimit = await this.walletProvider.estimateGas({ to: this.nftAddress, @@ -211,11 +231,7 @@ export class VWBLNFTMetaTx { data, }); console.log("estimate gas end"); - const forwarderContract = new ethers.Contract( - this.forwarderAddress, - forwarder.abi, - this.walletProvider.getSigner() - ); + const forwarderContract = new ethers.Contract(this.forwarderAddress, forwarder.abi, this.ethersSigner); const batchNonce = await forwarderContract.getNonce(myAddress, 0); const txParam: TxParam = buildForwardTxRequest( myAddress, @@ -224,26 +240,37 @@ export class VWBLNFTMetaTx { batchNonce, data ); - const domainSeparator = getDomainSeparator(this.forwarderAddress, chainId); - const dataToSign = getDataToSignForEIP712(txParam, this.forwarderAddress, chainId); - const sig = await this.walletProvider.send("eth_signTypedData_v3", [myAddress, dataToSign]); - return { txParam, sig, domainSeparator }; + + if (isWeb3Provider(this.walletProvider as IWeb3Provider)) { + const domainSeparator = getDomainSeparator(this.forwarderAddress, chainId); + const dataToSign = getDataToSignForEIP712(txParam, this.forwarderAddress, chainId); + const sig = await (this.walletProvider as ethers.providers.Web3Provider).send("eth_signTypedData_v3", [ + myAddress, + dataToSign, + ]); + const signatureType = "EIP712_SIGN"; + return { txParam, sig, domainSeparator, signatureType }; + } else { + const hashToSign = getDataToSignForPersonalSign(txParam); + const sig = await (this.walletProvider as ethers.Wallet).signMessage(hashToSign); + const signatureType = "PERSONAL_SIGN"; + return { txParam, sig, signatureType }; + } } - private async sendTransaction( + protected async sendTransaction( request: TxParam, sig: any, myAddress: string, - domainSeparator: string, + domainSeparator: string | undefined, methodApiId: string, signatureType: string ): Promise { - const params = [request, domainSeparator, sig]; - + const params = typeof domainSeparator === "undefined" ? [request, sig] : [request, domainSeparator, sig]; try { const headers = { "x-api-key": this.biconomyAPIKey, - "content-Type": "application/json;charset=utf-8", + "Content-Type": "application/json;charset=utf-8", }; const { data } = await axios.post( `https://api.biconomy.io/api/v2/meta-tx/native`, @@ -257,7 +284,9 @@ export class VWBLNFTMetaTx { { headers: headers } ); console.log("post meta tx resp", data); - const receipt = await this.walletProvider.waitForTransaction(data.txHash); + const receipt = isWeb3Provider(this.walletProvider as IWeb3Provider) + ? (this.walletProvider as ethers.providers.Web3Provider).waitForTransaction(data.txHash) + : (this.walletProvider as ethers.Wallet).provider.waitForTransaction(data.txHash); console.log("confirmed:", data.txHash); return receipt; } catch (error) { @@ -284,3 +313,11 @@ const parseToTokenId = (receipt: ethers.providers.TransactionReceipt): number => }); return tokenId; }; + +interface IWeb3Provider { + getSigner(): ethers.providers.JsonRpcSigner; +} + +const isWeb3Provider = (walletProvider: IWeb3Provider): walletProvider is IWeb3Provider => { + return walletProvider.getSigner !== undefined; +}; diff --git a/src/vwbl/blockchain/erc721/VWBLProtocol.ts b/src/vwbl/blockchain/erc721/VWBLProtocol.ts index 60810f5d..a27f9fde 100644 --- a/src/vwbl/blockchain/erc721/VWBLProtocol.ts +++ b/src/vwbl/blockchain/erc721/VWBLProtocol.ts @@ -3,34 +3,37 @@ import { Web3 } from "web3"; import vwbl from "../../../contract/VWBLERC721ERC2981.json"; import vwblIPFS from "../../../contract/VWBLERC721ERC2981ForMetadata.json"; import { getFeeSettingsBasedOnEnvironment } from "../../../util/transactionHelper"; -import { GasSettings } from "../../types"; +import { GasSettings, GrantViewPermissionTxParam, MintForIPFSTxParam, MintTxParam } from "../../types"; export class VWBLNFT { private contract: any; // eslint-disable-line - private web3: Web3; + protected web3: Web3; constructor(web3: Web3, address: string, isIpfs: boolean) { this.web3 = web3; this.contract = isIpfs ? new web3.eth.Contract(vwblIPFS.abi, address) : new web3.eth.Contract(vwbl.abi, address); } - async mintToken(decryptUrl: string, feeNumerator: number, documentId: string, gasSettings?: GasSettings) { + async mintToken(mintParam: MintTxParam) { const myAddress = (await this.web3.eth.getAccounts())[0]; const fee = await this.getFee(); let txSettings: unknown; - if (gasSettings?.gasPrice) { + if (mintParam.gasSettings?.gasPrice) { const gas = await this.contract.methods - .mint(decryptUrl, feeNumerator, documentId) + .mint(mintParam.decryptUrl, mintParam.feeNumerator, mintParam.documentId) .estimateGas({ from: myAddress, value: fee }); txSettings = { from: myAddress, value: fee, - gasPrice: gasSettings?.gasPrice, + gasPrice: mintParam.gasSettings?.gasPrice, gas, }; } else { const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = - getFeeSettingsBasedOnEnvironment(gasSettings?.maxPriorityFeePerGas, gasSettings?.maxFeePerGas); + getFeeSettingsBasedOnEnvironment( + mintParam.gasSettings?.maxPriorityFeePerGas, + mintParam.gasSettings?.maxFeePerGas + ); txSettings = { from: myAddress, value: fee, @@ -39,35 +42,39 @@ export class VWBLNFT { }; } console.log("transaction start"); - const receipt = await this.contract.methods.mint(decryptUrl, feeNumerator, documentId).send(txSettings); + const receipt = await this.contract.methods + .mint(mintParam.decryptUrl, mintParam.feeNumerator, mintParam.documentId) + .send(txSettings); console.log("transaction end"); const tokenId: number = receipt.events.Transfer.returnValues.tokenId; return tokenId; } - async mintTokenForIPFS( - metadataUrl: string, - decryptUrl: string, - feeNumerator: number, - documentId: string, - gasSettings?: GasSettings - ) { + async mintTokenForIPFS(mintForIPFSParam: MintForIPFSTxParam) { const myAddress = (await this.web3.eth.getAccounts())[0]; const fee = await this.getFee(); let txSettings: unknown; - if (gasSettings?.gasPrice) { + if (mintForIPFSParam.gasSettings?.gasPrice) { const gas = await this.contract.methods - .mint(metadataUrl, decryptUrl, feeNumerator, documentId) + .mint( + mintForIPFSParam.metadataUrl, + mintForIPFSParam.decryptUrl, + mintForIPFSParam.feeNumerator, + mintForIPFSParam.documentId + ) .estimateGas({ from: myAddress, value: fee }); txSettings = { from: myAddress, value: fee, - gasPrice: gasSettings?.gasPrice, + gasPrice: mintForIPFSParam.gasSettings?.gasPrice, gas, }; } else { const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = - getFeeSettingsBasedOnEnvironment(gasSettings?.maxPriorityFeePerGas, gasSettings?.maxFeePerGas); + getFeeSettingsBasedOnEnvironment( + mintForIPFSParam.gasSettings?.maxPriorityFeePerGas, + mintForIPFSParam.gasSettings?.maxFeePerGas + ); txSettings = { from: myAddress, value: fee, @@ -77,7 +84,12 @@ export class VWBLNFT { } console.log("transaction start"); const receipt = await this.contract.methods - .mint(metadataUrl, decryptUrl, feeNumerator, documentId) + .mint( + mintForIPFSParam.metadataUrl, + mintForIPFSParam.decryptUrl, + mintForIPFSParam.feeNumerator, + mintForIPFSParam.documentId + ) .send(txSettings); console.log("transaction end"); const tokenId: number = receipt.events.Transfer.returnValues.tokenId; @@ -111,6 +123,10 @@ export class VWBLNFT { return await this.contract.methods.getMinter(tokenId).call(); } + async checkViewPermission(tokenId: number, user: string) { + return await this.contract.methods.checkViewPermission(tokenId, user).call(); + } + async isOwnerOf(tokenId: number) { const myAddress = (await this.web3.eth.getAccounts())[0]; const owner = await this.getOwner(tokenId); @@ -123,6 +139,11 @@ export class VWBLNFT { return myAddress === minter; } + async isGranteeOf(tokenId: number) { + const myAddress = (await this.web3.eth.getAccounts())[0]; + return await this.checkViewPermission(tokenId, myAddress); + } + async getFee() { return await this.contract.methods.getFee().call(); } @@ -204,6 +225,55 @@ export class VWBLNFT { } await this.contract.methods.safeTransferFrom(myAddress, to, tokenId).send(txSettings); } + + async grantViewPermission(grantParam: GrantViewPermissionTxParam): Promise { + const myAddress = (await this.web3.eth.getAccounts())[0]; + let txSettings: unknown; + if (grantParam.gasSettings?.gasPrice) { + const gas = await this.contract.methods + .grantViewPermission(grantParam.tokenId, grantParam.grantee) + .estimateGas({ from: myAddress }); + txSettings = { + from: myAddress, + gasPrice: grantParam.gasSettings?.gasPrice, + gas, + }; + } else { + const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = + getFeeSettingsBasedOnEnvironment( + grantParam.gasSettings?.maxPriorityFeePerGas, + grantParam.gasSettings?.maxFeePerGas + ); + txSettings = { + from: myAddress, + maxPriorityFeePerGas: _maxPriorityFeePerGas, + maxFeePerGas: _maxFeePerGas, + }; + } + await this.contract.methods.grantViewPermission(grantParam.tokenId, grantParam.grantee).send(txSettings); + } + + async revokeViewPermission(tokenId: number, revoker: string, gasSettings?: GasSettings): Promise { + const myAddress = (await this.web3.eth.getAccounts())[0]; + let txSettings: unknown; + if (gasSettings?.gasPrice) { + const gas = await this.contract.methods.revokeViewPermission(tokenId, revoker).estimateGas({ from: myAddress }); + txSettings = { + from: myAddress, + gasPrice: gasSettings?.gasPrice, + gas, + }; + } else { + const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = + getFeeSettingsBasedOnEnvironment(gasSettings?.maxPriorityFeePerGas, gasSettings?.maxFeePerGas); + txSettings = { + from: myAddress, + maxPriorityFeePerGas: _maxPriorityFeePerGas, + maxFeePerGas: _maxFeePerGas, + }; + } + await this.contract.methods.revokeViewPermission(tokenId, revoker).send(txSettings); + } } const range = (length: number) => { diff --git a/src/vwbl/blockchain/erc721/VWBLProtocolEthers.ts b/src/vwbl/blockchain/erc721/VWBLProtocolEthers.ts index 096c9db9..53cdee8a 100644 --- a/src/vwbl/blockchain/erc721/VWBLProtocolEthers.ts +++ b/src/vwbl/blockchain/erc721/VWBLProtocolEthers.ts @@ -3,18 +3,18 @@ import { ethers } from "ethers"; import vwbl from "../../../contract/VWBLERC721ERC2981.json"; import vwblIPFS from "../../../contract/VWBLERC721ERC2981ForMetadata.json"; import { getFeeSettingsBasedOnEnvironment } from "../../../util/transactionHelper"; -import { GasSettings } from "../../types"; +import { GasSettings, GrantViewPermissionTxParam, MintForIPFSTxParam, MintTxParam } from "../../types"; export class VWBLNFTEthers { - private ethersProvider: ethers.providers.BaseProvider; - private ethersSigner: ethers.providers.JsonRpcSigner | ethers.Wallet; + protected ethersProvider: ethers.providers.BaseProvider; + private ethersSigner: ethers.Signer; private contract: ethers.Contract; constructor( address: string, isIpfs: boolean, ethersProvider: ethers.providers.BaseProvider, - ethersSigner: ethers.providers.JsonRpcSigner | ethers.Wallet + ethersSigner: ethers.Signer ) { this.ethersProvider = ethersProvider; this.ethersSigner = ethersSigner; @@ -23,17 +23,20 @@ export class VWBLNFTEthers { : new ethers.Contract(address, vwbl.abi, ethersSigner); } - async mintToken(decryptUrl: string, feeNumerator: number, documentId: string, gasSettings?: GasSettings) { + async mintToken(mintParam: MintTxParam) { const fee = await this.getFee(); let txSettings: unknown; - if (gasSettings?.gasPrice) { + if (mintParam.gasSettings?.gasPrice) { txSettings = { value: fee, - gasPrice: gasSettings?.gasPrice, + gasPrice: mintParam.gasSettings?.gasPrice, }; } else { const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = - getFeeSettingsBasedOnEnvironment(gasSettings?.maxPriorityFeePerGas, gasSettings?.maxFeePerGas); + getFeeSettingsBasedOnEnvironment( + mintParam.gasSettings?.maxPriorityFeePerGas, + mintParam.gasSettings?.maxFeePerGas + ); txSettings = { value: fee, maxPriorityFeePerGas: _maxPriorityFeePerGas, @@ -41,30 +44,27 @@ export class VWBLNFTEthers { }; } console.log("transaction start"); - const tx = await this.contract.mint(decryptUrl, feeNumerator, documentId, txSettings); + const tx = await this.contract.mint(mintParam.decryptUrl, mintParam.feeNumerator, mintParam.documentId, txSettings); const receipt = await this.ethersProvider.waitForTransaction(tx.hash); console.log("transaction end"); const tokenId = parseToTokenId(receipt); return tokenId; } - async mintTokenForIPFS( - metadataUrl: string, - decryptUrl: string, - feeNumerator: number, - documentId: string, - gasSettings?: GasSettings - ) { + async mintTokenForIPFS(mintForIPFSParam: MintForIPFSTxParam) { const fee = await this.getFee(); let txSettings: unknown; - if (gasSettings?.gasPrice) { + if (mintForIPFSParam.gasSettings?.gasPrice) { txSettings = { value: fee, - gasPrice: gasSettings?.gasPrice, + gasPrice: mintForIPFSParam.gasSettings?.gasPrice, }; } else { const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = - getFeeSettingsBasedOnEnvironment(gasSettings?.maxPriorityFeePerGas, gasSettings?.maxFeePerGas); + getFeeSettingsBasedOnEnvironment( + mintForIPFSParam.gasSettings?.maxPriorityFeePerGas, + mintForIPFSParam.gasSettings?.maxFeePerGas + ); txSettings = { value: fee, maxPriorityFeePerGas: _maxPriorityFeePerGas, @@ -72,7 +72,13 @@ export class VWBLNFTEthers { }; } console.log("transaction start"); - const tx = await this.contract.mint(metadataUrl, decryptUrl, feeNumerator, documentId, txSettings); + const tx = await this.contract.mint( + mintForIPFSParam.metadataUrl, + mintForIPFSParam.decryptUrl, + mintForIPFSParam.feeNumerator, + mintForIPFSParam.documentId, + txSettings + ); const receipt = await this.ethersProvider.waitForTransaction(tx.hash); console.log("transaction end"); const tokenId = parseToTokenId(receipt); @@ -106,6 +112,10 @@ export class VWBLNFTEthers { return await this.contract.callStatic.getMinter(tokenId); } + async checkViewPermission(tokenId: number, user: string) { + return await this.contract.callStatic.checkViewPermission(tokenId, user); + } + async isOwnerOf(tokenId: number) { const myAddress = await this.ethersSigner.getAddress(); const owner = await this.getOwner(tokenId); @@ -118,6 +128,11 @@ export class VWBLNFTEthers { return myAddress === minter; } + async isGranteeOf(tokenId: number) { + const myAddress = await this.ethersSigner.getAddress(); + return await this.checkViewPermission(tokenId, myAddress); + } + async getFee() { return await this.contract.callStatic.getFee(); } @@ -188,13 +203,52 @@ export class VWBLNFTEthers { const tx = await this.contract.safeTransferFrom(myAddress, to, tokenId, txSettings); await this.ethersProvider.waitForTransaction(tx.hash); } + + async grantViewPermission(grantParam: GrantViewPermissionTxParam): Promise { + let txSettings: unknown; + if (grantParam.gasSettings?.gasPrice) { + txSettings = { + gasPrice: grantParam.gasSettings?.gasPrice, + }; + } else { + const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = + getFeeSettingsBasedOnEnvironment( + grantParam.gasSettings?.maxPriorityFeePerGas, + grantParam.gasSettings?.maxFeePerGas + ); + txSettings = { + maxPriorityFeePerGas: _maxPriorityFeePerGas, + maxFeePerGas: _maxFeePerGas, + }; + } + const tx = await this.contract.grantViewPermission(grantParam.tokenId, grantParam.grantee, txSettings); + await this.ethersProvider.waitForTransaction(tx.hash); + } + + async revokeViewPermission(tokenId: number, revoker: string, gasSettings?: GasSettings): Promise { + let txSettings: unknown; + if (gasSettings?.gasPrice) { + txSettings = { + gasPrice: gasSettings?.gasPrice, + }; + } else { + const { maxPriorityFeePerGas: _maxPriorityFeePerGas, maxFeePerGas: _maxFeePerGas } = + getFeeSettingsBasedOnEnvironment(gasSettings?.maxPriorityFeePerGas, gasSettings?.maxFeePerGas); + txSettings = { + maxPriorityFeePerGas: _maxPriorityFeePerGas, + maxFeePerGas: _maxFeePerGas, + }; + } + const tx = await this.contract.revokeViewPermission(tokenId, revoker, txSettings); + await this.ethersProvider.waitForTransaction(tx.hash); + } } const range = (length: number) => { return Array.from(Array(length).keys()); }; -const parseToTokenId = (receipt: ethers.providers.TransactionReceipt): number => { +export const parseToTokenId = (receipt: ethers.providers.TransactionReceipt): number => { const eventInterface = new ethers.utils.Interface([ "event nftDataRegistered(address contractAddress, uint256 tokenId)", ]); diff --git a/src/vwbl/blockchain/index.ts b/src/vwbl/blockchain/index.ts index f1d968c2..b0c1f5df 100644 --- a/src/vwbl/blockchain/index.ts +++ b/src/vwbl/blockchain/index.ts @@ -4,3 +4,6 @@ export * from "./erc721/VWBLMetaTxProtocol"; export * from "./erc721/VWBLProtocolEthers"; export * from "./erc1155/VWBLProtocol"; export * from "./erc1155/VWBLProtocolEthers"; +export * from "./erc6150/VWBLProtocol"; +export * from "./erc6150/VWBLProtocolEthers"; +export * from "./erc6150/VWBLMetaTxProtocol"; diff --git a/src/vwbl/erc6150/VWBL.ts b/src/vwbl/erc6150/VWBL.ts new file mode 100644 index 00000000..0f6d6889 --- /dev/null +++ b/src/vwbl/erc6150/VWBL.ts @@ -0,0 +1,357 @@ +import { utils } from "ethers"; +import * as fs from "fs"; + +import { uploadEncryptedFile, uploadMetadata, uploadThumbnail } from "../../storage/aws"; +import { createRandomKey, encryptFile, encryptStream, encryptString, getMimeType, toBase64FromBlob } from "../../util"; +import { VWBLERC6150Ethers, VWBLERC6150Web3 } from "../blockchain/"; +import { VWBL } from "../erc721/VWBL"; +import { + ConstructorProps, + EncryptLogic, + EthersConstructorProps, + FileOrPath, + GasSettings, + GrantViewPermission, + ManagedCreateToken, + ManagedCreateTokenForIPFS, + MintToken, + MintTokenForIPFS, + ProgressSubscriber, + StepStatus, + UploadContentType, + UploadEncryptedFile, + UploadMetadata, + UploadMetadataType, + UploadThumbnail, +} from "../types"; + +export class VWBLERC6150 extends VWBL { + public erc6150: VWBLERC6150Web3 | VWBLERC6150Ethers; + + constructor(props: ConstructorProps | EthersConstructorProps) { + super(props); + this.erc6150 = + "web3" in props + ? new VWBLERC6150Web3(props.web3, props.contractAddress, props.uploadMetadataType === UploadMetadataType.IPFS) + : new VWBLERC6150Ethers( + props.contractAddress, + props.uploadMetadataType === UploadMetadataType.IPFS, + props.ethersProvider, + props.ethersSigner + ); + } + + /** + * Create VWBL ERC6150 + * + * @remarks + * The following happens: Minting ERC6150, Uploading encrypted data, Uploading metadata, Setting key to VWBL Network + * By default, metadata will be uploaded to Amazon S3. + * You need to pass `uploadFileCallback` and `uploadMetadataCallBack` if you upload metadata to a storage other than Amazon S3. + * + * @param name - The ERC6150 name + * @param description - The ERC6150 description + * @param plainFile - The data that only ERC6150 owner can view + * @param thumbnailImage - The ERC6150 image + * @param feeNumerator - This basis point of the sale price will be paid to the ERC6150 creator every time the ERC6150 is sold or re-sold. Ex. If feNumerator = 3.5*10^2, royalty is 3.5% + * @param encryptLogic - Select ether "base64" or "binary". Selection criteria: "base64" -> sutable for small data. "binary" -> sutable for large data. + * @param uploadEncryptedFileCallback - Optional: the function for uploading encrypted data + * @param uploadThumbnailCallback - Optional: the function for uploading thumbnail + * @param uploadMetadataCallBack - Optional: the function for uploading metadata + * @param subscriber - Optional: the subscriber for seeing progress + * @param gasSettings - Optional: the object whose keys are maxPriorityFeePerGas, maxFeePerGas and gasPrice + * @param parentId - Optional: The Id of parent token. If parentId param is undefined or 0, mint as root token(parentId=0) + * @returns + */ + managedCreateToken: ManagedCreateToken = async ( + name: string, + description: string, + plainFile: FileOrPath | FileOrPath[], + thumbnailImage: FileOrPath, + feeNumerator: number, + encryptLogic: EncryptLogic = "base64", + uploadEncryptedFileCallback?: UploadEncryptedFile, + uploadThumbnailCallback?: UploadThumbnail, + uploadMetadataCallBack?: UploadMetadata, + subscriber?: ProgressSubscriber, + gasSettings?: GasSettings, + parentId?: number + ) => { + if (!this.signature) { + throw "please sign first"; + } + const { uploadContentType, uploadMetadataType, awsConfig, vwblNetworkUrl } = this.opts; + // 1. mint token + const documentId = utils.hexlify(utils.randomBytes(32)); + const _parentId = typeof parentId !== "undefined" ? parentId : 0; + const tokenId = await this.erc6150.mintToken({ + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + gasSettings, + parentId: _parentId, + }); + subscriber?.kickStep(StepStatus.MINT_TOKEN); + + // 2. create key in frontend + const key = createRandomKey(); + subscriber?.kickStep(StepStatus.CREATE_KEY); + + // 3. encrypt data + console.log("encrypt data"); + const plainFileArray = [plainFile].flat(); + const uuid = createRandomKey(); + const uploadEncryptedFunction = + uploadContentType === UploadContentType.S3 ? uploadEncryptedFile : uploadEncryptedFileCallback; + const uploadThumbnailFunction = + uploadContentType === UploadContentType.S3 ? uploadThumbnail : uploadThumbnailCallback; + if (!uploadEncryptedFunction || !uploadThumbnailFunction) { + throw new Error("please specify upload file type or give callback"); + } + subscriber?.kickStep(StepStatus.ENCRYPT_DATA); + + // 4. upload data + console.log("upload data"); + const isRunningOnBrowser = typeof window !== "undefined"; + const encryptedDataUrls = await Promise.all( + plainFileArray.map(async (file) => { + const plainFileBlob = file instanceof File ? file : new File([await fs.promises.readFile(file)], file); + const filePath = file instanceof File ? file.name : file; + const fileName: string = file instanceof File ? file.name : file.split("/").slice(-1)[0]; //ファイル名の取得だけのためにpathを使いたくなかった + const encryptedContent = + encryptLogic === "base64" + ? encryptString(await toBase64FromBlob(plainFileBlob), key) + : isRunningOnBrowser + ? await encryptFile(plainFileBlob, key) + : encryptStream(fs.createReadStream(filePath), key); + return await uploadEncryptedFunction(fileName, encryptedContent, uuid, awsConfig); + }) + ); + const thumbnailImageUrl = await uploadThumbnailFunction(thumbnailImage, uuid, awsConfig); + subscriber?.kickStep(StepStatus.UPLOAD_CONTENT); + + // 5. upload metadata + console.log("upload meta data"); + const uploadMetadataFunction = + uploadMetadataType === UploadMetadataType.S3 ? uploadMetadata : uploadMetadataCallBack; + if (!uploadMetadataFunction) { + throw new Error("please specify upload metadata type or give callback"); + } + const mimeType = getMimeType(plainFileArray[0]) || ""; + await uploadMetadataFunction( + tokenId, + name, + description, + thumbnailImageUrl, + encryptedDataUrls, + mimeType, + encryptLogic, + awsConfig + ); + subscriber?.kickStep(StepStatus.UPLOAD_METADATA); + + // 6. set key to vwbl-network + console.log("set key"); + const chainId = + "web3" in this.opts ? Number(await this.opts.web3.eth.getChainId()) : await this.opts.ethersSigner.getChainId(); + const signerAddress = + "web3" in this.opts + ? await this._getAddressBySigner(this.opts.web3) + : await this._getAddressBySigner(this.opts.ethersSigner); + await this.api.setKey(documentId, chainId, key, this.signature, signerAddress); + subscriber?.kickStep(StepStatus.SET_KEY); + + return tokenId; + }; + + /** + * Create VWBL ERC6150 which metadata on IPFS. + * + * @remarks + * The following happens: Minting ERC6150, Uploading encrypted data, Uploading metadata, Setting key to VWBL Network + * metadata will be uploaded to IPFS. + * You need to pass `uploadFileCallback` and `uploadMetadataCallBack` if you upload metadata to a storage other than Amazon S3. + * + * @param name - The ERC6150 name + * @param description - The ERC6150 description + * @param plainFile - The data that only ERC6150 owner can view + * @param thumbnailImage - The ERC6150 image + * @param feeNumerator - This basis point of the sale price will be paid to the ERC6150 creator every time the ERC6150 is sold or re-sold. Ex. If feNumerator = 3.5*10^2, royalty is 3.5% + * @param encryptLogic - Select ether "base64" or "binary". Selection criteria: "base64" -> sutable for small data. "binary" -> sutable for large data. + * @param subscriber - Optional: the subscriber for seeing progress + * @param gasSettings - Optional: the object whose keys are maxPriorityFeePerGas, maxFeePerGas and gasPrice + * @param parentId - Optional: The Id of parent token. If parentId param is undefined or 0, mint as root token(parentId=0) + * @returns + */ + managedCreateTokenForIPFS: ManagedCreateTokenForIPFS = async ( + name: string, + description: string, + plainFile: FileOrPath | FileOrPath[], + thumbnailImage: FileOrPath, + feeNumerator: number, + encryptLogic: EncryptLogic = "base64", + subscriber?: ProgressSubscriber, + gasSettings?: GasSettings, + parentId?: number + ) => { + if (!this.signature) { + throw "please sign first"; + } + const { vwblNetworkUrl } = this.opts; + // 1. create key in frontend + const key = createRandomKey(); + subscriber?.kickStep(StepStatus.CREATE_KEY); + + // 2. encrypt data + console.log("encrypt data"); + const plainFileArray = [plainFile].flat(); + subscriber?.kickStep(StepStatus.ENCRYPT_DATA); + + // 3. upload data + console.log("upload data"); + const encryptedDataUrls = await Promise.all( + plainFileArray.map(async (file) => { + const plainFileBlob = file instanceof File ? file : new File([await fs.promises.readFile(file)], file); + const filePath = file instanceof File ? file.name : file; + const fileName: string = file instanceof File ? file.name : file.split("/").slice(-1)[0]; //ファイル名の取得だけのためにpathを使いたくなかった + const encryptedContent = + encryptLogic === "base64" + ? encryptString(await toBase64FromBlob(plainFileBlob), key) + : await encryptFile(plainFileBlob, key); + return await this.uploadToIpfs?.uploadEncryptedFile(encryptedContent); + }) + ); + const thumbnailImageUrl = await this.uploadToIpfs?.uploadThumbnail(thumbnailImage); + subscriber?.kickStep(StepStatus.UPLOAD_CONTENT); + + // 4. upload metadata + console.log("upload meta data"); + const mimeType = getMimeType(plainFileArray[0]); + const metadataUrl = await this.uploadToIpfs?.uploadMetadata( + name, + description, + thumbnailImageUrl as string, + encryptedDataUrls as string[], + mimeType, + encryptLogic + ); + subscriber?.kickStep(StepStatus.UPLOAD_METADATA); + + // 5. mint token + const documentId = utils.hexlify(utils.randomBytes(32)); + const _parentId = typeof parentId !== "undefined" ? parentId : 0; + const tokenId = await this.erc6150.mintTokenForIPFS({ + metadataUrl: metadataUrl as string, + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + gasSettings, + parentId: _parentId, + }); + subscriber?.kickStep(StepStatus.MINT_TOKEN); + + // 6. set key to vwbl-network + console.log("set key"); + const chainId = + "web3" in this.opts ? Number(await this.opts.web3.eth.getChainId()) : await this.opts.ethersSigner.getChainId(); + const signerAddress = + "web3" in this.opts + ? await this._getAddressBySigner(this.opts.web3) + : await this._getAddressBySigner(this.opts.ethersSigner); + await this.api.setKey(documentId, chainId, key, this.signature, signerAddress); + subscriber?.kickStep(StepStatus.SET_KEY); + + return tokenId; + }; + + /** + * Mint new ERC6150 + * + * @param feeNumerator - This basis point of the sale price will be paid to the ERC6150 creator every time the ERC6150 is sold or re-sold. Ex. If feNumerator = 3.5*10^2, royalty is 3.5% + * @param maxPriorityFeePerGas - Optional: the maxPriorityFeePerGas field in EIP-1559 + * @param maxFeePerGas - Optional: the maxFeePerGas field in EIP-1559 + * @param parentId - Optional: The Id of parent token. If parentId param is undefined or 0, mint as root token(parentId=0) + * @returns The ID of minted ERC6150 + */ + mintToken: MintToken = async ( + feeNumerator: number, + gasSettings?: GasSettings, + parentId?: number + ): Promise => { + const { vwblNetworkUrl } = this.opts; + const documentId = utils.hexlify(utils.randomBytes(32)); + const _parentId = typeof parentId !== "undefined" ? parentId : 0; + return await this.erc6150.mintToken({ + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + gasSettings, + parentId: _parentId, + }); + }; + + /** + * Mint new ERC6150 + * + * @param metadataUrl metadata url + * @param feeNumerator - This basis point of the sale price will be paid to the ERC6150 creator every time the ERC6150 is sold or re-sold. Ex. If feNumerator = 3.5*10^2, royalty is 3.5% + * @param maxPriorityFeePerGas - Optional: the maxPriorityFeePerGas field in EIP-1559 + * @param maxFeePerGas - Optional: the maxFeePerGas field in EIP-1559 + * @param parentId - Optional: The Id of parent token. If parentId param is undefined or 0, mint as root token(parentId=0) + * @returns The ID of minted ERC6150 + */ + mintTokenForIPFS: MintTokenForIPFS = async ( + metadataUrl: string, + feeNumerator: number, + gasSettings?: GasSettings, + parentId?: number + ): Promise => { + const { vwblNetworkUrl } = this.opts; + const documentId = utils.hexlify(utils.randomBytes(32)); + const _parentId = typeof parentId !== "undefined" ? parentId : 0; + return await this.erc6150.mintTokenForIPFS({ + metadataUrl, + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + gasSettings, + parentId: _parentId, + }); + }; + + /** + * Grant view permission + * + * @param tokenId - The ID of ERC6150 + * @param grantee - The wallet address of a grantee + * @param gasSettings - Optional: the object whose keys are maxPriorityFeePerGas, maxFeePerGas and gasPrice + * @param toDir - Optional: A boolean indicating whether to grant view permission directly or single ERC6150 token. + * If toDir param is undefined or false, grant view permission to single ERC6150 token. + * + */ + grantViewPermission: GrantViewPermission = async ( + tokenId: number, + grantee: string, + gasSettings?: GasSettings, + toDir?: boolean + ): Promise => { + const _toDir = typeof toDir !== "undefined" ? toDir : false; + await this.erc6150.grantViewPermission({ + tokenId, + grantee, + gasSettings, + toDir: _toDir, + }); + }; + + /** + * Revoke view permission to directory (ERC6150 under parent token) + * + * @param tokenId - The ID of ERC6150 + * @param revoker - The wallet address of a revoker + * @param gasSettings - Optional: the object whose keys are maxPriorityFeePerGas, maxFeePerGas and gasPrice + */ + revokeDirPermission = async (tokenId: number, revoker: string, gasSettings?: GasSettings) => { + await this.erc6150.revokeDirPermission(tokenId, revoker, gasSettings); + }; +} diff --git a/src/vwbl/erc6150/VWBLMetaTx.ts b/src/vwbl/erc6150/VWBLMetaTx.ts new file mode 100644 index 00000000..38ad85c3 --- /dev/null +++ b/src/vwbl/erc6150/VWBLMetaTx.ts @@ -0,0 +1,338 @@ +import { ethers, utils } from "ethers"; +import * as fs from "fs"; + +import { uploadEncryptedFile, uploadMetadata, uploadThumbnail } from "../../storage/aws"; +import { createRandomKey, encryptFile, encryptStream, encryptString, getMimeType, toBase64FromBlob } from "../../util"; +import { VWBLERC6150MetaTxEthers } from "../blockchain"; +import { VWBLMetaTx } from "../erc721/VWBLMetaTx"; +import { + EncryptLogic, + FileOrPath, + GrantViewPermissionMetaTx, + ManagedCreateTokenForIPFSMetaTx, + ManagedCreateTokenMetatx, + MetaTxConstructorProps, + MintTokenForIPFSMetaTx, + MintTokenMetaTx, + ProgressSubscriber, + StepStatus, + UploadContentType, + UploadEncryptedFile, + UploadMetadata, + UploadMetadataType, + UploadThumbnail, +} from "../types"; + +export class VWBLERC6150MetaTx extends VWBLMetaTx { + public erc6150: VWBLERC6150MetaTxEthers; + + constructor(props: MetaTxConstructorProps) { + super(props); + const { bcProvider, contractAddress, biconomyConfig } = props; + + const walletProvider = "address" in bcProvider ? bcProvider : new ethers.providers.Web3Provider(bcProvider); + this.erc6150 = new VWBLERC6150MetaTxEthers( + biconomyConfig.apiKey, + walletProvider, + contractAddress, + biconomyConfig.forwarderAddress + ); + } + + /** + * Create VWBL ERC6150 + * + * @remarks + * The following happens: Minting ERC6150, Uploading encrypted data, Uploading metadata, Setting key to VWBL Network + * By default, metadata will be uploaded to Amazon S3. + * You need to pass `uploadFileCallback` and `uploadMetadataCallBack` if you upload metadata to a storage other than Amazon S3. + * + * @param name - The ERC6150 name + * @param description - The ERC6150 description + * @param plainFile - The data that only ERC6150 owner can view + * @param thumbnailImage - The ERC6150 image + * @param feeNumerator - This basis point of the sale price will be paid to the ERC6150 creator every time the ERC6150 is sold or re-sold. Ex. If feNumerator = 3.5*10^2, royalty is 3.5% + * @param encryptLogic - Select ether "base64" or "binary". Selection criteria: "base64" -> sutable for small data. "binary" -> sutable for large data. + * @param mintApiId - The mint method api id of biconomy + * @param uploadEncryptedFileCallback - Optional: the function for uploading encrypted data + * @param uploadThumbnailCallback - Optional: the function for uploading thumbnail + * @param uploadMetadataCallBack - Optional: the function for uploading metadata + * @param subscriber - Optional: the subscriber for seeing progress + * @param parentId - Optional: The Id of parent token. If parentId param is undefined or 0, mint as root token(parentId=0) + * @returns + */ + managedCreateToken: ManagedCreateTokenMetatx = async ( + name: string, + description: string, + plainFile: FileOrPath | FileOrPath[], + thumbnailImage: FileOrPath, + feeNumerator: number, + encryptLogic: EncryptLogic = "base64", + mintApiId: string, + uploadEncryptedFileCallback?: UploadEncryptedFile, + uploadThumbnailCallback?: UploadThumbnail, + uploadMetadataCallBack?: UploadMetadata, + subscriber?: ProgressSubscriber, + parentId?: number + ) => { + if (!this.signature) { + throw "please sign first"; + } + const { uploadContentType, uploadMetadataType, awsConfig, vwblNetworkUrl } = this.opts; + // 1. mint token + const documentId = utils.hexlify(utils.randomBytes(32)); + const _parentId = typeof parentId !== "undefined" ? parentId : 0; + const tokenId = await this.erc6150.mintToken({ + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + mintApiId, + parentId: _parentId, + }); + subscriber?.kickStep(StepStatus.MINT_TOKEN); + + // 2. create key in frontend + const key = createRandomKey(); + subscriber?.kickStep(StepStatus.CREATE_KEY); + + // 3. encrypt data + console.log("encrypt data"); + const plainFileArray = [plainFile].flat(); + const uuid = createRandomKey(); + const uploadEncryptedFunction = + uploadContentType === UploadContentType.S3 ? uploadEncryptedFile : uploadEncryptedFileCallback; + const uploadThumbnailFunction = + uploadContentType === UploadContentType.S3 ? uploadThumbnail : uploadThumbnailCallback; + if (!uploadEncryptedFunction || !uploadThumbnailFunction) { + throw new Error("please specify upload file type or give callback"); + } + subscriber?.kickStep(StepStatus.ENCRYPT_DATA); + + // 4. upload data + console.log("upload data"); + const isRunningOnBrowser = typeof window !== "undefined"; + const encryptedDataUrls = await Promise.all( + plainFileArray.map(async (file) => { + const plainFileBlob = file instanceof File ? file : new File([await fs.promises.readFile(file)], file); + const filePath = file instanceof File ? file.name : file; + const fileName: string = file instanceof File ? file.name : file.split("/").slice(-1)[0]; //ファイル名の取得だけのためにpathを使いたくなかった + const encryptedContent = + encryptLogic === "base64" + ? encryptString(await toBase64FromBlob(plainFileBlob), key) + : isRunningOnBrowser + ? await encryptFile(plainFileBlob, key) + : encryptStream(fs.createReadStream(filePath), key); + return await uploadEncryptedFunction(fileName, encryptedContent, uuid, awsConfig); + }) + ); + const thumbnailImageUrl = await uploadThumbnailFunction(thumbnailImage, uuid, awsConfig); + subscriber?.kickStep(StepStatus.UPLOAD_CONTENT); + + // 5. upload metadata + console.log("upload meta data"); + const uploadMetadataFunction = + uploadMetadataType === UploadMetadataType.S3 ? uploadMetadata : uploadMetadataCallBack; + if (!uploadMetadataFunction) { + throw new Error("please specify upload metadata type or give callback"); + } + const mimeType = getMimeType(plainFileArray[0]); + await uploadMetadataFunction( + tokenId, + name, + description, + thumbnailImageUrl, + encryptedDataUrls, + mimeType, + encryptLogic, + awsConfig + ); + subscriber?.kickStep(StepStatus.UPLOAD_METADATA); + + // 6. set key to vwbl-network + console.log("set key"); + const chainId = await this.signer.getChainId(); + await this.api.setKey(documentId, chainId, key, this.signature, await this._getAddressBySigner(this.signer)); + subscriber?.kickStep(StepStatus.SET_KEY); + + return tokenId; + }; + + /** + * Create VWBL ERC6150 which metadata on IPFS. + * + * @remarks + * The following happens: Minting ERC6150, Uploading encrypted data, Uploading metadata, Setting key to VWBL Network + * metadata will be uploaded to IPFS. + * You need to pass `uploadFileCallback` and `uploadMetadataCallBack` if you upload metadata to a storage other than Amazon S3. + * + * @param name - The ERC6150 name + * @param description - The ERC6150 description + * @param plainFile - The data that only ERC6150 owner can view + * @param thumbnailImage - The ERC6150 image + * @param feeNumerator - This basis point of the sale price will be paid to the ERC6150 creator every time the ERC6150 is sold or re-sold. Ex. If feNumerator = 3.5*10^2, royalty is 3.5% + * @param encryptLogic - Select ether "base64" or "binary". Selection criteria: "base64" -> sutable for small data. "binary" -> sutable for large data. + * @param mintApiId - The mint method api id of biconomy + * @param subscriber - Optional: the subscriber for seeing progress + * @param parentId - Optional: The Id of parent token. If parentId param is undefined or 0, mint as root token(parentId=0) + * @returns + */ + managedCreateTokenForIPFS: ManagedCreateTokenForIPFSMetaTx = async ( + name: string, + description: string, + plainFile: FileOrPath | FileOrPath[], + thumbnailImage: FileOrPath, + feeNumerator: number, + encryptLogic: EncryptLogic = "base64", + mintApiId: string, + subscriber?: ProgressSubscriber, + parentId?: number + ) => { + if (!this.signature) { + throw "please sign first"; + } + const { vwblNetworkUrl } = this.opts; + // 1. create key in frontend + const key = createRandomKey(); + subscriber?.kickStep(StepStatus.CREATE_KEY); + + // 2. encrypt data + console.log("encrypt data"); + const plainFileArray = [plainFile].flat(); + subscriber?.kickStep(StepStatus.ENCRYPT_DATA); + + // 3. upload data + console.log("upload data"); + const encryptedDataUrls = await Promise.all( + plainFileArray.map(async (file) => { + const plainFileBlob = file instanceof File ? file : new File([await fs.promises.readFile(file)], file); + const filePath = file instanceof File ? file.name : file; + const fileName: string = file instanceof File ? file.name : file.split("/").slice(-1)[0]; //ファイル名の取得だけのためにpathを使いたくなかった + const encryptedContent = + encryptLogic === "base64" + ? encryptString(await toBase64FromBlob(plainFileBlob), key) + : await encryptFile(plainFileBlob, key); + return await this.uploadToIpfs?.uploadEncryptedFile(encryptedContent); + }) + ); + subscriber?.kickStep(StepStatus.UPLOAD_CONTENT); + + const thumbnailImageUrl = await this.uploadToIpfs?.uploadThumbnail(thumbnailImage); + // 4. upload metadata + console.log("upload meta data"); + const mimeType = getMimeType(plainFileArray[0]); + const metadataUrl = await this.uploadToIpfs?.uploadMetadata( + name, + description, + thumbnailImageUrl as string, + encryptedDataUrls as string[], + mimeType, + encryptLogic + ); + subscriber?.kickStep(StepStatus.UPLOAD_METADATA); + + // 5. mint token + const documentId = utils.hexlify(utils.randomBytes(32)); + const _parentId = typeof parentId !== "undefined" ? parentId : 0; + const tokenId = await this.erc6150.mintTokenForIPFS({ + metadataUrl: metadataUrl as string, + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + mintApiId, + parentId: _parentId, + }); + subscriber?.kickStep(StepStatus.MINT_TOKEN); + + // 6. set key to vwbl-network + console.log("set key"); + const chainId = await this.signer.getChainId(); + await this.api.setKey(documentId, chainId, key, this.signature, await this._getAddressBySigner(this.signer)); + subscriber?.kickStep(StepStatus.SET_KEY); + + return tokenId; + }; + + /** + * Mint new ERC6150 + * + * @param feeNumerator - This basis point of the sale price will be paid to the ERC6150 creator every time the ERC6150 is sold or re-sold. Ex. If feNumerator = 3.5*10^2, royalty is 3.5% + * @param mintApiId - The mint method api id of biconomy + * @param parentId - Optional: The Id of parent token. If parentId param is undefined or 0, mint as root token(parentId=0) + * @returns The ID of minted ERC6150 + */ + mintToken: MintTokenMetaTx = async (feeNumerator: number, mintApiId: string, parentId?: number): Promise => { + const { vwblNetworkUrl } = this.opts; + const documentId = utils.hexlify(utils.randomBytes(32)); + const _parentId = typeof parentId !== "undefined" ? parentId : 0; + return await this.erc6150.mintToken({ + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + mintApiId, + parentId: _parentId, + }); + }; + + /** + * Mint new ERC6150 + * + * @param metadataUrl metadata url + * @param feeNumerator - This basis point of the sale price will be paid to the ERC6150 creator every time the ERC6150 is sold or re-sold. Ex. If feNumerator = 3.5*10^2, royalty is 3.5% + * @param mintApiId - The mint method api id of biconomy + * @param parentId - Optional: The Id of parent token. If parentId param is undefined or 0, mint as root token(parentId=0) + * @returns The ID of minted ERC6150 + */ + mintTokenForIPFS: MintTokenForIPFSMetaTx = async ( + metadataUrl: string, + feeNumerator: number, + mintApiId: string, + parentId?: number + ): Promise => { + const { vwblNetworkUrl } = this.opts; + const documentId = utils.hexlify(utils.randomBytes(32)); + const _parentId = typeof parentId !== "undefined" ? parentId : 0; + return await this.erc6150.mintTokenForIPFS({ + metadataUrl, + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + mintApiId, + parentId: _parentId, + }); + }; + + /** + * Grant view permission + * + * @param tokenId - The ID of ERC6150 + * @param grantee - The wallet address of a grantee + * @param grantViewPermissionApiId - The grantViewPermission api id of biconomy + * @param toDir - Optional: A boolean indicating whether to grant view permission directly or single ERC6150 token. + * If toDir param is undefined or false, grant view permission to single ERC6150 token. + */ + grantViewPermission: GrantViewPermissionMetaTx = async ( + tokenId: number, + grantee: string, + grantViewPermissionApiId: string, + toDir?: boolean + ): Promise => { + const _toDir = typeof toDir !== "undefined" ? toDir : false; + await this.erc6150.grantViewPermission({ + tokenId, + grantee, + grantViewPermissionApiId, + toDir: _toDir, + }); + }; + + /** + * Revoke view permission to directory (ERC6150 under parent token) + * + * @param tokenId - The ID of ERC6150 + * @param revoker - The wallet address of a revoker + * @param revokeDirPermissionApiId - The revokeDirPermissionApiId api id of biconomy + */ + revokeDirPermission = async (tokenId: number, revoker: string, revokeDirPermissionApiId: string) => { + await this.erc6150.revokeDirPermission(tokenId, revoker, revokeDirPermissionApiId); + }; +} diff --git a/src/vwbl/erc721/VWBL.ts b/src/vwbl/erc721/VWBL.ts index c9e9a7a0..7a3176ae 100644 --- a/src/vwbl/erc721/VWBL.ts +++ b/src/vwbl/erc721/VWBL.ts @@ -23,6 +23,11 @@ import { EthersConstructorProps, FileOrPath, GasSettings, + GrantViewPermission, + ManagedCreateToken, + ManagedCreateTokenForIPFS, + MintToken, + MintTokenForIPFS, ProgressSubscriber, StepStatus, UploadContentType, @@ -100,7 +105,7 @@ export class VWBL extends VWBLBase { * @param gasSettings - Optional: the object whose keys are maxPriorityFeePerGas, maxFeePerGas and gasPrice * @returns */ - managedCreateToken = async ( + managedCreateToken: ManagedCreateToken = async ( name: string, description: string, plainFile: FileOrPath | FileOrPath[], @@ -119,7 +124,12 @@ export class VWBL extends VWBLBase { const { uploadContentType, uploadMetadataType, awsConfig, vwblNetworkUrl } = this.opts; // 1. mint token const documentId = utils.hexlify(utils.randomBytes(32)); - const tokenId = await this.nft.mintToken(vwblNetworkUrl, feeNumerator, documentId, gasSettings); + const tokenId = await this.nft.mintToken({ + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + gasSettings, + }); subscriber?.kickStep(StepStatus.MINT_TOKEN); // 2. create key in frontend @@ -211,7 +221,7 @@ export class VWBL extends VWBLBase { * @param gasSettings - Optional: the object whose keys are maxPriorityFeePerGas, maxFeePerGas and gasPrice * @returns */ - managedCreateTokenForIPFS = async ( + managedCreateTokenForIPFS: ManagedCreateTokenForIPFS = async ( name: string, description: string, plainFile: FileOrPath | FileOrPath[], @@ -266,13 +276,13 @@ export class VWBL extends VWBLBase { // 5. mint token const documentId = utils.hexlify(utils.randomBytes(32)); - const tokenId = await this.nft.mintTokenForIPFS( - metadataUrl as string, - vwblNetworkUrl, + const tokenId = await this.nft.mintTokenForIPFS({ + metadataUrl: metadataUrl as string, + decryptUrl: vwblNetworkUrl, feeNumerator, documentId, - gasSettings - ); + gasSettings, + }); subscriber?.kickStep(StepStatus.MINT_TOKEN); // 6. set key to vwbl-network @@ -328,12 +338,14 @@ export class VWBL extends VWBLBase { * @param maxFeePerGas - Optional: the maxFeePerGas field in EIP-1559 * @returns The ID of minted NFT */ - mintToken = async (feeNumerator: number, gasSettings?: GasSettings): Promise => { + mintToken: MintToken = async (feeNumerator: number, gasSettings?: GasSettings): Promise => { const { vwblNetworkUrl } = this.opts; const documentId = utils.hexlify(utils.randomBytes(32)); - return await this.nft.mintToken(vwblNetworkUrl, feeNumerator, documentId, { - maxPriorityFeePerGas: gasSettings?.maxPriorityFeePerGas, - maxFeePerGas: gasSettings?.maxFeePerGas, + return await this.nft.mintToken({ + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + gasSettings, }); }; @@ -342,12 +354,24 @@ export class VWBL extends VWBLBase { * * @param metadataUrl metadata url * @param feeNumerator - This basis point of the sale price will be paid to the NFT creator every time the NFT is sold or re-sold. Ex. If feNumerator = 3.5*10^2, royalty is 3.5% + * @param maxPriorityFeePerGas - Optional: the maxPriorityFeePerGas field in EIP-1559 + * @param maxFeePerGas - Optional: the maxFeePerGas field in EIP-1559 * @returns The ID of minted NFT */ - mintTokenForIPFS = async (metadataUrl: string, feeNumerator: number): Promise => { + mintTokenForIPFS: MintTokenForIPFS = async ( + metadataUrl: string, + feeNumerator: number, + gasSettings?: GasSettings + ): Promise => { const { vwblNetworkUrl } = this.opts; const documentId = utils.hexlify(utils.randomBytes(32)); - return await this.nft.mintTokenForIPFS(metadataUrl, vwblNetworkUrl, feeNumerator, documentId); + return await this.nft.mintTokenForIPFS({ + metadataUrl, + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + gasSettings, + }); }; /** @@ -403,6 +427,36 @@ export class VWBL extends VWBLBase { await this.nft.safeTransfer(to, tokenId, gasSettings); }; + /** + * Grant view permission + * + * @param tokenId - The ID of NFT + * @param grantee - The wallet address of a grantee + * @param gasSettings - Optional: the object whose keys are maxPriorityFeePerGas, maxFeePerGas and gasPrice + */ + grantViewPermission: GrantViewPermission = async ( + tokenId: number, + grantee: string, + gasSettings?: GasSettings + ): Promise => { + await this.nft.grantViewPermission({ + tokenId, + grantee, + gasSettings, + }); + }; + + /** + * Revoke view permission + * + * @param tokenId - The ID of NFT + * @param revoker - The wallet address of revoker + * @param gasSettings - Optional: the object whose keys are maxPriorityFeePerGas, maxFeePerGas and gasPrice + */ + revokeViewPermission = async (tokenId: number, revoker: string, gasSettings?: GasSettings): Promise => { + await this.nft.revokeViewPermission(tokenId, revoker, gasSettings); + }; + /** * Uplod Metadata * @@ -514,9 +568,12 @@ export class VWBL extends VWBLBase { * @returns Token metadata and an address of NFT owner */ getTokenById = async (tokenId: number): Promise<(ExtractMetadata | Metadata) & { owner: string }> => { - const isOwnerOrMinter = (await this.nft.isOwnerOf(tokenId)) || (await this.nft.isMinterOf(tokenId)); + const canViewData = + (await this.nft.isOwnerOf(tokenId)) || + (await this.nft.isMinterOf(tokenId)) || + (await this.nft.isGranteeOf(tokenId)); const owner = await this.nft.getOwner(tokenId); - const metadata = isOwnerOrMinter ? await this.extractMetadata(tokenId) : await this.getMetadata(tokenId); + const metadata = canViewData ? await this.extractMetadata(tokenId) : await this.getMetadata(tokenId); if (!metadata) { throw new Error("metadata not found"); } diff --git a/src/vwbl/erc721/VWBLEthers.ts b/src/vwbl/erc721/VWBLEthers.ts index 0e85b1dc..475aea53 100644 --- a/src/vwbl/erc721/VWBLEthers.ts +++ b/src/vwbl/erc721/VWBLEthers.ts @@ -101,7 +101,11 @@ export class VWBLEthers extends VWBLBase { const { uploadContentType, uploadMetadataType, awsConfig, vwblNetworkUrl } = this.opts; // 1. mint token const documentId = utils.hexlify(utils.randomBytes(32)); - const tokenId = await this.nft.mintToken(vwblNetworkUrl, feeNumerator, documentId); + const tokenId = await this.nft.mintToken({ + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + }); subscriber?.kickStep(StepStatus.MINT_TOKEN); // 2. create key in frontend @@ -247,7 +251,12 @@ export class VWBLEthers extends VWBLBase { // 5. mint token const documentId = utils.hexlify(utils.randomBytes(32)); - const tokenId = await this.nft.mintTokenForIPFS(metadataUrl as string, vwblNetworkUrl, feeNumerator, documentId); + const tokenId = await this.nft.mintTokenForIPFS({ + metadataUrl: metadataUrl as string, + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + }); subscriber?.kickStep(StepStatus.MINT_TOKEN); // 6. set key to vwbl-network @@ -296,7 +305,29 @@ export class VWBLEthers extends VWBLBase { mintToken = async (feeNumerator: number): Promise => { const { vwblNetworkUrl } = this.opts; const documentId = utils.hexlify(utils.randomBytes(32)); - return await this.nft.mintToken(vwblNetworkUrl, feeNumerator, documentId); + return await this.nft.mintToken({ + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + }); + }; + + /** + * Mint new NFT + * + * @param metadataUrl metadata url + * @param feeNumerator - This basis point of the sale price will be paid to the NFT creator every time the NFT is sold or re-sold. Ex. If feNumerator = 3.5*10^2, royalty is 3.5% + * @returns The ID of minted NFT + */ + mintTokenForIPFS = async (metadataUrl: string, feeNumerator: number): Promise => { + const { vwblNetworkUrl } = this.opts; + const documentId = utils.hexlify(utils.randomBytes(32)); + return await this.nft.mintTokenForIPFS({ + metadataUrl: metadataUrl, + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + }); }; /** @@ -349,6 +380,29 @@ export class VWBLEthers extends VWBLBase { await this.nft.safeTransfer(to, tokenId); }; + /** + * Grant view permission + * + * @param tokenId - The ID of NFT + * @param grantee - The wallet address of a grantee + */ + grantViewPermission = async (tokenId: number, grantee: string): Promise => { + await this.nft.grantViewPermission({ + tokenId, + grantee, + }); + }; + + /** + * Revoke view permission + * + * @param tokenId - The ID of NFT + * @param revoker - The wallet address of revoker + */ + revokeViewPermission = async (tokenId: number, revoker: string): Promise => { + await this.nft.revokeViewPermission(tokenId, revoker); + }; + /** * Uplod Metadata * @@ -460,9 +514,12 @@ export class VWBLEthers extends VWBLBase { * @returns Token metadata and an address of NFT owner */ getTokenById = async (tokenId: number): Promise<(ExtractMetadata | Metadata) & { owner: string }> => { - const isOwnerOrMinter = (await this.nft.isOwnerOf(tokenId)) || (await this.nft.isMinterOf(tokenId)); + const canViewData = + (await this.nft.isOwnerOf(tokenId)) || + (await this.nft.isMinterOf(tokenId)) || + (await this.nft.isGranteeOf(tokenId)); const owner = await this.nft.getOwner(tokenId); - const metadata = isOwnerOrMinter ? await this.extractMetadata(tokenId) : await this.getMetadata(tokenId); + const metadata = canViewData ? await this.extractMetadata(tokenId) : await this.getMetadata(tokenId); if (!metadata) { throw new Error("metadata not found"); } diff --git a/src/vwbl/erc721/VWBLMetaTx.ts b/src/vwbl/erc721/VWBLMetaTx.ts index 72c3c462..a58fc6fd 100644 --- a/src/vwbl/erc721/VWBLMetaTx.ts +++ b/src/vwbl/erc721/VWBLMetaTx.ts @@ -20,7 +20,13 @@ import { ExtractMetadata, Metadata, PlainMetadata } from "../metadata"; import { EncryptLogic, FileOrPath, + GrantViewPermissionMetaTx, + ManagedCreateTokenForIPFSMetaTx, + ManagedCreateTokenMetatx, MetaTxConstructorProps, + MintTokenForIPFS, + MintTokenForIPFSMetaTx, + MintTokenMetaTx, ProgressSubscriber, StepStatus, UploadContentType, @@ -35,7 +41,7 @@ import { VWBLViewer } from "../viewer"; export class VWBLMetaTx extends VWBLBase { public opts: VWBLMetaTxOption; public nft: VWBLNFTMetaTx; - public signer: ethers.providers.JsonRpcSigner; + public signer: ethers.Signer; public viewer?: VWBLViewer; constructor(props: MetaTxConstructorProps) { @@ -43,14 +49,16 @@ export class VWBLMetaTx extends VWBLBase { this.opts = props; const { bcProvider, contractAddress, biconomyConfig, dataCollectorAddress } = props; - const walletProvider = new ethers.providers.Web3Provider(bcProvider); - this.signer = walletProvider.getSigner(); + + const walletProvider = "address" in bcProvider ? bcProvider : new ethers.providers.Web3Provider(bcProvider); + this.signer = "address" in bcProvider ? bcProvider : (walletProvider as ethers.providers.Web3Provider).getSigner(); this.nft = new VWBLNFTMetaTx( biconomyConfig.apiKey, walletProvider, contractAddress, biconomyConfig.forwarderAddress ); + if (dataCollectorAddress) { this.viewer = new VWBLViewer({ provider: walletProvider, @@ -91,7 +99,7 @@ export class VWBLMetaTx extends VWBLBase { * @param subscriber - Optional: the subscriber for seeing progress * @returns */ - managedCreateToken = async ( + managedCreateToken: ManagedCreateTokenMetatx = async ( name: string, description: string, plainFile: FileOrPath | FileOrPath[], @@ -110,7 +118,12 @@ export class VWBLMetaTx extends VWBLBase { const { uploadContentType, uploadMetadataType, awsConfig, vwblNetworkUrl } = this.opts; // 1. mint token const documentId = utils.hexlify(utils.randomBytes(32)); - const tokenId = await this.nft.mintToken(vwblNetworkUrl, feeNumerator, documentId, mintApiId); + const tokenId = await this.nft.mintToken({ + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + mintApiId, + }); subscriber?.kickStep(StepStatus.MINT_TOKEN); // 2. create key in frontend @@ -197,7 +210,7 @@ export class VWBLMetaTx extends VWBLBase { * @param subscriber - Optional: the subscriber for seeing progress * @returns */ - managedCreateTokenForIPFS = async ( + managedCreateTokenForIPFS: ManagedCreateTokenForIPFSMetaTx = async ( name: string, description: string, plainFile: FileOrPath | FileOrPath[], @@ -252,13 +265,13 @@ export class VWBLMetaTx extends VWBLBase { // 5. mint token const documentId = utils.hexlify(utils.randomBytes(32)); - const tokenId = await this.nft.mintTokenForIPFS( - metadataUrl as string, - vwblNetworkUrl, + const tokenId = await this.nft.mintTokenForIPFS({ + metadataUrl: metadataUrl as string, + decryptUrl: vwblNetworkUrl, feeNumerator, documentId, - mintApiId - ); + mintApiId, + }); subscriber?.kickStep(StepStatus.MINT_TOKEN); // 6. set key to vwbl-network @@ -299,10 +312,39 @@ export class VWBLMetaTx extends VWBLBase { * @param mintApiId - The mint method api id of biconomy * @returns The ID of minted NFT */ - mintToken = async (feeNumerator: number, mintApiId: string): Promise => { + mintToken: MintTokenMetaTx = async (feeNumerator: number, mintApiId: string): Promise => { + const { vwblNetworkUrl } = this.opts; + const documentId = utils.hexlify(utils.randomBytes(32)); + return await this.nft.mintToken({ + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + mintApiId, + }); + }; + + /** + * Mint new NFT + * + * @param metadataUrl metadata url + * @param feeNumerator - This basis point of the sale price will be paid to the NFT creator every time the NFT is sold or re-sold. Ex. If feNumerator = 3.5*10^2, royalty is 3.5% + * @param mintApiId - The mint method api id of biconomy + * @returns The ID of minted NFT + */ + mintTokenForIPFS: MintTokenForIPFSMetaTx = async ( + metadataUrl: string, + feeNumerator: number, + mintApiId: string + ): Promise => { const { vwblNetworkUrl } = this.opts; const documentId = utils.hexlify(utils.randomBytes(32)); - return await this.nft.mintToken(vwblNetworkUrl, feeNumerator, documentId, mintApiId); + return await this.nft.mintTokenForIPFS({ + metadataUrl, + decryptUrl: vwblNetworkUrl, + feeNumerator, + documentId, + mintApiId, + }); }; /** @@ -358,6 +400,36 @@ export class VWBLMetaTx extends VWBLBase { await this.nft.safeTransfer(to, tokenId, safeTransferFromApiId); }; + /** + * Grant view permission + * + * @param tokenId - The ID of NFT + * @param grantee - The wallet address of a grantee + * @param grantViewPermissionApiId - The grantViewPermission api id of biconomy + */ + grantViewPermission: GrantViewPermissionMetaTx = async ( + tokenId: number, + grantee: string, + grantViewPermissionApiId: string + ): Promise => { + await this.nft.grantViewPermission({ + tokenId, + grantee, + grantViewPermissionApiId, + }); + }; + + /** + * Revoke view permission + * + * @param tokenId - The ID of NFT + * @param revoker - The wallet address of revoker + * @param revokeViewPermisionApiId - The revokeViewPermission api id of biconomy + */ + revokeViewPermission = async (tokenId: number, revoker: string, revokeViewPermisionApiId: string): Promise => { + await this.nft.revokeViewPermission(tokenId, revoker, revokeViewPermisionApiId); + }; + /** * Uplod Metadata * @@ -469,9 +541,12 @@ export class VWBLMetaTx extends VWBLBase { * @returns Token metadata and an address of NFT owner */ getTokenById = async (tokenId: number): Promise<(ExtractMetadata | Metadata) & { owner: string }> => { - const isOwnerOrMinter = (await this.nft.isOwnerOf(tokenId)) || (await this.nft.isMinterOf(tokenId)); + const canViewData = + (await this.nft.isOwnerOf(tokenId)) || + (await this.nft.isMinterOf(tokenId)) || + (await this.nft.isGranteeOf(tokenId)); const owner = await this.nft.getOwner(tokenId); - const metadata = isOwnerOrMinter ? await this.extractMetadata(tokenId) : await this.getMetadata(tokenId); + const metadata = canViewData ? await this.extractMetadata(tokenId) : await this.getMetadata(tokenId); if (!metadata) { throw new Error("metadata not found"); } diff --git a/src/vwbl/index.ts b/src/vwbl/index.ts index be66078d..19f35b43 100644 --- a/src/vwbl/index.ts +++ b/src/vwbl/index.ts @@ -3,6 +3,8 @@ export * from "./erc721/VWBLMetaTx"; export * from "./erc721/VWBLEthers"; export * from "./erc1155/VWBL"; export * from "./erc1155/VWBLEthers"; +export * from "./erc6150/VWBL"; +export * from "./erc6150/VWBLMetaTx"; export * from "./metadata"; export * from "./types"; export * from "./blockchain"; diff --git a/src/vwbl/types/ConstructorPropsType.ts b/src/vwbl/types/ConstructorPropsType.ts index 14996f9f..c5369a76 100644 --- a/src/vwbl/types/ConstructorPropsType.ts +++ b/src/vwbl/types/ConstructorPropsType.ts @@ -26,7 +26,7 @@ export type VWBLOption = ConstructorProps; export type EthersConstructorProps = BaseConstructorProps & { ethersProvider: ethers.providers.BaseProvider; - ethersSigner: ethers.providers.JsonRpcSigner | ethers.Wallet; + ethersSigner: ethers.Signer; manageKeyType?: ManageKeyType; dataCollectorAddress?: string; }; @@ -34,7 +34,7 @@ export type EthersConstructorProps = BaseConstructorProps & { export type VWBLEthersOption = EthersConstructorProps; export type MetaTxConstructorProps = BaseConstructorProps & { - bcProvider: ethers.providers.ExternalProvider | ethers.providers.JsonRpcFetchFunc; + bcProvider: ethers.providers.ExternalProvider | ethers.providers.JsonRpcFetchFunc | ethers.Wallet; biconomyConfig: BiconomyConfig; manageKeyType?: ManageKeyType; dataCollectorAddress?: string; @@ -43,7 +43,7 @@ export type MetaTxConstructorProps = BaseConstructorProps & { export type VWBLMetaTxOption = MetaTxConstructorProps; export type ViewerConstructorProps = { - provider: Web3 | ethers.providers.BaseProvider; + provider: Web3 | ethers.providers.BaseProvider | ethers.Wallet; dataCollectorAddress: string; }; diff --git a/src/vwbl/types/TxParamType.ts b/src/vwbl/types/TxParamType.ts new file mode 100644 index 00000000..243f539d --- /dev/null +++ b/src/vwbl/types/TxParamType.ts @@ -0,0 +1,34 @@ +import { GasSettings } from "./GasSettings"; + +export type MintTxParam = { + decryptUrl: string; + feeNumerator: number; + documentId: string; + gasSettings?: GasSettings; + // param of ERC6150 + parentId?: number; +}; + +export type MintMetaTxParam = MintTxParam & { + mintApiId: string; +}; + +export type MintForIPFSTxParam = MintTxParam & { + metadataUrl: string; +}; + +export type MintForIPFSMetaTxParam = MintForIPFSTxParam & { + mintApiId: string; +}; + +export type GrantViewPermissionTxParam = { + tokenId: number; + grantee: string; + gasSettings?: GasSettings; + // param of ERC6150 + toDir?: boolean; +}; + +export type GrantViewPermissionMetaTxParam = GrantViewPermissionTxParam & { + grantViewPermissionApiId: string; +}; diff --git a/src/vwbl/types/VWBLERC721ERC6150Type.ts b/src/vwbl/types/VWBLERC721ERC6150Type.ts new file mode 100644 index 00000000..cd7bdbfb --- /dev/null +++ b/src/vwbl/types/VWBLERC721ERC6150Type.ts @@ -0,0 +1,177 @@ +import { + EncryptLogic, + FileOrPath, + GasSettings, + ProgressSubscriber, + UploadEncryptedFile, + UploadMetadata, + UploadThumbnail, +} from "./index"; + +export type ManagedCreateToken = { + // Interface for ERC721 + ( + name: string, + description: string, + plainFile: FileOrPath | FileOrPath[], + thumbnailImage: FileOrPath, + feeNumerator: number, + encryptLogic: EncryptLogic, + uploadEncryptedFileCallback?: UploadEncryptedFile, + uploadThumbnailCallback?: UploadThumbnail, + uploadMetadataCallBack?: UploadMetadata, + subscriber?: ProgressSubscriber, + gasSettings?: GasSettings + ): Promise; + + // Interface for ERC6150 + ( + name: string, + description: string, + plainFile: FileOrPath | FileOrPath[], + thumbnailImage: FileOrPath, + feeNumerator: number, + encryptLogic: EncryptLogic, + uploadEncryptedFileCallback?: UploadEncryptedFile, + uploadThumbnailCallback?: UploadThumbnail, + uploadMetadataCallBack?: UploadMetadata, + subscriber?: ProgressSubscriber, + gasSettings?: GasSettings, + parentId?: number + ): Promise; +}; + +export type ManagedCreateTokenForIPFS = { + // Interface for ERC721 + ( + name: string, + description: string, + plainFile: FileOrPath | FileOrPath[], + thumbnailImage: FileOrPath, + feeNumerator: number, + encryptLogic: EncryptLogic, + subscriber?: ProgressSubscriber, + gasSettings?: GasSettings + ): Promise; + + // Interface for ERC6150 + ( + name: string, + description: string, + plainFile: FileOrPath | FileOrPath[], + thumbnailImage: FileOrPath, + feeNumerator: number, + encryptLogic: EncryptLogic, + subscriber?: ProgressSubscriber, + gasSettings?: GasSettings, + parentId?: number + ): Promise; +}; + +export type MintToken = { + // Interface for ERC721 + (feeNumerator: number, gasSettings?: GasSettings): Promise; + + // Interface for ERC6150 + (feeNumerator: number, gasSettings?: GasSettings, parentId?: number): Promise; +}; + +export type MintTokenForIPFS = { + // Interface for ERC721 + (metadataUrl: string, feeNumerator: number, gasSettings?: GasSettings): Promise; + + // Interface for ERC6150 + (metadataUrl: string, feeNumerator: number, gasSettings?: GasSettings, parentId?: number): Promise; +}; + +export type GrantViewPermission = { + // Interface for ERC721 + (tokenId: number, grantee: string, gasSettings?: GasSettings): Promise; + + // Interface for ERC6150 + (tokenId: number, grantee: string, gasSettings?: GasSettings, toDir?: boolean): Promise; +}; + +export type ManagedCreateTokenMetatx = { + // Interface for ERC721 + ( + name: string, + description: string, + plainFile: FileOrPath | FileOrPath[], + thumbnailImage: FileOrPath, + feeNumerator: number, + encryptLogic: EncryptLogic, + mintApiId: string, + uploadEncryptedFileCallback?: UploadEncryptedFile, + uploadThumbnailCallback?: UploadThumbnail, + uploadMetadataCallBack?: UploadMetadata, + subscriber?: ProgressSubscriber + ): Promise; + + // Interface for ERC6150 + ( + name: string, + description: string, + plainFile: FileOrPath | FileOrPath[], + thumbnailImage: FileOrPath, + feeNumerator: number, + encryptLogic: EncryptLogic, + mintApiId: string, + uploadEncryptedFileCallback?: UploadEncryptedFile, + uploadThumbnailCallback?: UploadThumbnail, + uploadMetadataCallBack?: UploadMetadata, + subscriber?: ProgressSubscriber, + parentId?: number + ): Promise; +}; + +export type ManagedCreateTokenForIPFSMetaTx = { + // Interface for ERC721 + ( + name: string, + description: string, + plainFile: FileOrPath | FileOrPath[], + thumbnailImage: FileOrPath, + feeNumerator: number, + encryptLogic: EncryptLogic, + mintApiId: string, + subscriber?: ProgressSubscriber + ): Promise; + + // Interface for ERC6150 + ( + name: string, + description: string, + plainFile: FileOrPath | FileOrPath[], + thumbnailImage: FileOrPath, + feeNumerator: number, + encryptLogic: EncryptLogic, + mintApiId: string, + subscriber?: ProgressSubscriber, + parentId?: number + ): Promise; +}; + +export type MintTokenMetaTx = { + // Interface for ERC721 + (feeNumerator: number, mintApiId: string): Promise; + + // Interface for ERC6150 + (feeNumerator: number, mintApiId: string, parentId?: number): Promise; +}; + +export type MintTokenForIPFSMetaTx = { + // Interface for ERC721 + (metadataUrl: string, feeNumerator: number, mintApiId: string): Promise; + + // Interface for ERC6150 + (metadataUrl: string, feeNumerator: number, mintApiId: string, parentId?: number): Promise; +}; + +export type GrantViewPermissionMetaTx = { + // Interface for ERC721 + (tokenId: number, grantee: string, grantViewPermissionApiId: string): Promise; + + // Interface for ERC6150 + (tokenId: number, grantee: string, grantViewPermissionApiId: string, toDir?: boolean): Promise; +}; diff --git a/src/vwbl/types/index.ts b/src/vwbl/types/index.ts index 220d25d1..8fd0ee3a 100644 --- a/src/vwbl/types/index.ts +++ b/src/vwbl/types/index.ts @@ -7,3 +7,5 @@ export * from "./ProgressSubscriber"; export * from "./BiconomyConfigType"; export * from "./ConstructorPropsType"; export * from "./GasSettings"; +export * from "./TxParamType"; +export * from "./VWBLERC721ERC6150Type"; diff --git a/test/unit/vwbl/VWBL.test.ts b/test/unit/vwbl/VWBL.test.ts index 1dafa0f3..31f17f83 100644 --- a/test/unit/vwbl/VWBL.test.ts +++ b/test/unit/vwbl/VWBL.test.ts @@ -21,7 +21,7 @@ const vwblApiStub = { setKey: sinon.stub(VWBLApi.prototype, "setKey"), }; -const providerUrl = "https://rpc-mumbai.maticvigil.com/"; +const providerUrl = "https://rpc-amoy.polygon.technology/"; // preparation for web3.js const web3 = new Web3(providerUrl as string); @@ -85,7 +85,7 @@ describe("VWBL with web3.js", () => { ); expect(vwblProtocolStub.mintToken.callCount).equal(1); - expect(vwblProtocolStub.mintToken.getCall(0).args[3]).equal(undefined); + expect(vwblProtocolStub.mintToken.getCall(0).args[0].gasSettings).equal(undefined); expect(vwblApiStub.setKey.callCount).equal(1); expect(uploadEncryptedFileStub.callCount).equal(1); expect(uploadFileStub.callCount).equal(1); @@ -113,7 +113,7 @@ describe("VWBL with web3.js", () => { ); expect(vwblProtocolStub.mintToken.callCount).equal(2); - expect(vwblProtocolStub.mintToken.getCall(1).args[3]).deep.equal({maxPriorityFeePerGas: 40000000000, maxFeePerGas: 41000000000}); + expect(vwblProtocolStub.mintToken.getCall(1).args[0].gasSettings).deep.equal({maxPriorityFeePerGas: 40000000000, maxFeePerGas: 41000000000}); expect(vwblApiStub.setKey.callCount).equal(2); expect(uploadEncryptedFileStub.callCount).equal(2); expect(uploadFileStub.callCount).equal(2); @@ -141,7 +141,7 @@ describe("VWBL with web3.js", () => { ); expect(vwblProtocolStub.mintToken.callCount).equal(3); - expect(vwblProtocolStub.mintToken.getCall(2).args[3]).deep.equal({gasPrice: 1000}); + expect(vwblProtocolStub.mintToken.getCall(2).args[0].gasSettings).deep.equal({gasPrice: 1000}); expect(vwblApiStub.setKey.callCount).equal(3); expect(uploadEncryptedFileStub.callCount).equal(3); expect(uploadFileStub.callCount).equal(3); @@ -322,7 +322,7 @@ describe("VWBL with ethers.js", () => { ); expect(vwblProtocolStub.mintToken.callCount).equal(1); - expect(vwblProtocolStub.mintToken.getCall(0).args[3]).equal(undefined); + expect(vwblProtocolStub.mintToken.getCall(0).args[0].gasSettings).equal(undefined); expect(vwblApiStub.setKey.callCount).equal(7); expect(uploadEncryptedFileStub.callCount).equal(1); expect(uploadFileStub.callCount).equal(1); @@ -350,7 +350,7 @@ describe("VWBL with ethers.js", () => { ); expect(vwblProtocolStub.mintToken.callCount).equal(2); - expect(vwblProtocolStub.mintToken.getCall(1).args[3]).deep.equal({maxPriorityFeePerGas: 40000000000, maxFeePerGas: 41000000000}); + expect(vwblProtocolStub.mintToken.getCall(1).args[0].gasSettings).deep.equal({maxPriorityFeePerGas: 40000000000, maxFeePerGas: 41000000000}); expect(vwblApiStub.setKey.callCount).equal(8); expect(uploadEncryptedFileStub.callCount).equal(2); expect(uploadFileStub.callCount).equal(2); @@ -378,7 +378,7 @@ describe("VWBL with ethers.js", () => { ); expect(vwblProtocolStub.mintToken.callCount).equal(3); - expect(vwblProtocolStub.mintToken.getCall(2).args[3]).deep.equal({gasPrice: 1000}); + expect(vwblProtocolStub.mintToken.getCall(2).args[0].gasSettings).deep.equal({gasPrice: 1000}); expect(vwblApiStub.setKey.callCount).equal(9); expect(uploadEncryptedFileStub.callCount).equal(3); expect(uploadFileStub.callCount).equal(3); diff --git a/yarn.lock b/yarn.lock index b4e9a102..38c14b0b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2834,7 +2834,7 @@ resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== -"@truffle/hdwallet-provider@^2.1.11": +"@truffle/hdwallet-provider@^2.1.15": version "2.1.15" resolved "https://registry.yarnpkg.com/@truffle/hdwallet-provider/-/hdwallet-provider-2.1.15.tgz#fbf8e19d112db81b109ebc06ac6d9d42124b512c" integrity sha512-I5cSS+5LygA3WFzru9aC5+yDXVowEEbLCx0ckl/RqJ2/SCiYXkzYlR5/DjjDJuCtYhivhrn2RP9AheeFlRF+qw== @@ -2955,6 +2955,13 @@ dependencies: bignumber.js "7.2.1" +"@types/ethereumjs-abi@^0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@types/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz#a28c8b18b76c388575d40ac29d580b8040311b38" + integrity sha512-2XOUOXXqYkWtZ5550hM0vdjwH3ccm1Q/4bowJWuXYmx2KpDTN7BrgADC563IYJdnltYnPrZhaHJxbuagjtNuAg== + dependencies: + "@types/node" "*" + "@types/graceful-fs@^4.1.3": version "4.1.9" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4"