World NFTs
World NFTs are used to manage VeVerse worlds and register portals between different worlds.
Getting started
Install Foundry.
Run tests: forge test
Installation
npm i @veverse/world_nfts
JS API
First import the methods you need like: import {utils, availableIdentity, availableAvatar} from '@veverse/world_nfts'
.
For documentation of utils
, please check CRS docs.
available(string name, string chainId) returns (boolean promise)
Checks if specific name wasn't registered already.
```js
await available("JohnDoe", "4")
```
rentPrice(string name, integer duration, string chainId) returns ([address, BigNumber] promise)
Checks if there is any fee to register / renew this CRS record, returns contract address of ERC20 token and the fee amount. In case address is zero, it means that fee should be paid in gas coin, which is managed by register
automatically, call erc20Approve
if there is non-zero fee in ERC20 token.
makeCommitment(string name, address owner, bytes32 secret, string chainId) returns (bytes32 promise)
Generates commitment hash for the provided secret.
```js
const owner = "0x0000000000000000000000000000000000000000"
const secret = ethers.utils.randomBytes(32)
const commitment = await makeCommitment("JohnDoe", "4")
```
commit(string name, bytes32 commitment, bytes pass, string chainId) returns (transaction promise)
Commitment version with whitelisted pass.
```js
await commit(name, commitment, pass, "4")
```
Pass can be generated using the following code:
```js
const permit = async function(privKey, address, name) {
const whitelistMessage = ethers.utils.keccak256(
ethers.utils.defaultAbiCoder.encode(
["bytes32", "address", "string"], [
await getDomainSeparator(),
address,
name
],
),
)
const signer = new ethers.Wallet(privKey)
const whitelistSignature = await signer.signMessage(ethers.utils.arrayify(whitelistMessage))
const sig = ethers.utils.splitSignature(
ethers.utils.arrayify(whitelistSignature)
);
const pass = ethers.utils.defaultAbiCoder.encode(
["uint8", "bytes32", "bytes32"], [sig.v, sig.r, sig.s],
)
return pass
}
```
Domain separator can be also generated off-chain using the following code:
```js
function domain(chainId, verifyingContract) {
return {
name: "IdentityWhitelist",
version: "v1",
chainId,
verifyingContract
}
}
const chainId = "1" // Ethereum Mainnet
const contractDomain = ethers.utils._TypedDataEncoder.hashDomain(
identityDomainSeparator(chainId)
)
```
register(string name, address owner, integer duration, bytes32 secret, string chainId) returns (transaction promise)
All variables should be the same as used on makeCommitment
step. Some CRS may require approval of a relevant ERC20 token, before running this transaction. This can be done with utils.erc20Approve
call.
```js
const owner = "0x0000000000000000000000000000000000000000"
const duration = 31556952 // 1 year in seconds
await register("JohnDoe", owner, duration, secret, "4")
```
setText(string node, string key, string value, string chainId) returns (transaction promise)
Store text record on-chain, node
can be generated from name or NFT utils.nameToNode('johndoe.xr')
or utils.idToNode(86745341786912841616557368118532256523691956314975099975829920571153145112669)
. Stored value can be read with getText
for the same node and key.
getText(string node, string key, string chainId) returns (string promise)
Read previously stored string value for the key
. Check setText
for the details of node
generation.
setNftImage(string node, string url, string chainId) returns (transaction promise)
Helper to customise on-chain NFT image in metadata.
getNftImage(string node, string chainId) returns (string promise)
Read custom NFT image, can be empty if no custom image is stored on-chain. Use getMetadataByNftId
to get properly resolved image either in image
or image_data
key.
getNameByNftId(integer id, string chainId) returns (string promise)
Read name (e.g. johndoe
) without zone suffix by NFT id, id
can be generated from name or node utils.nameToId('johndoe.xr')
or utils.nodeToId(0x777151c19673b9106ec9ea201594cfe56d2d330c0f5ece6cf938ece42f978a1a)
. As with getNftImage
, you get the same data by using getMetadataByNftId
in a name
key with zone suffix.
getMetadataByNftId(integer id, string chainId) returns (object promise)
Read NFT metadata by id, id
can be generated from name or node as described in getNameByNftId
.
```json
{
"name":"johndoe.xr",
"description":"Ownership deed of VeVerse world",
"image_data":"<svg>...</svg>",
"attributes":[{"trait_type":"Type","value":"VeVerse World"}]
}
```
getNftsForWallet(address wallet, string chainId) returns ([string] promise)
Returns the list of NFT ids owned by specific wallet. Ids are returned as strings in a hex form e.g. 0x27cf60eaf7291bc5004051bead7742d568b25692edcfee3d2ee7e1b047c49382
```js
const nftIds = await getNftsForWallet('0x42b3830ac0781c9dc46d94a2a5a830bd10797aec', '4')
```
Smart contract API
WorldNFTV1
uses default CRS NFT interface.
WorldControllerV1
uses default gated controller interface.
WorldResolver
The following API extends default resolver interface.
hasRole(bytes32 _node, bytes4 _roleSig, address _manager) returns (bool)
Check if specific _manager
was granted role with _roleSig
, signature is generated like bytes4(keccak256("ROLE_NAME"))
.
setRole(bytes32 _node, bytes4 _roleSig, address _manager, bool _active)
Grant or revoke role with _roleSig
to _manager
address by passing true
or false
in _active
. Role signature is generated like bytes4(keccak256("ROLE_NAME"))
.
Deployments
To deploy, run scripts with the relevant environment variables: source .secret && CRS_REGISTRY_ADDRESS=0xf754b8De91Bd619227B5DF74c760B58048A4095D RESOLVER_ADDRESS=0x0000000000000000000000000000000000000000 forge script script/DeployAll.s.sol:DeployAllScript --rpc-url $RINKEBY_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key $ETHERSCAN_KEY -vvvv --slow
.
For existing CRS and resolver deployments (if you just need to upgrade NFTs and controllers) you can use the following constants to set the address: CRS_REGISTRY_ADDRESS
and CRS_RESOLVER_ADDRESS
.
To deploy metadata proxy: source .secret && CONTROLLER_ADDRESS=0x4230c3cbd66e62e96ca8d997809e0c99b9615683 forge script script/DeployMetadata.s.sol:DeployMetadataScript --rpc-url $RINKEBY_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key $ETHERSCAN_KEY -vvvv --slow
.
Rinkeby
- Registry:
0xf754b8De91Bd619227B5DF74c760B58048A4095D
- Resolver:
0xc71ff4deab4ba2e99e93e8406cf2fa252dd14545
- Controller:
0x4230c3cbd66e62e96ca8d997809e0c99b9615683
- NFT:
0xdd32abef08ec0fa24d169a990cff1ee81bfa1bc0