@le7el/core_nfts
v0.7.0
Published
LE7EL identity, avatar and investor NFTs
Downloads
65
Readme
Avatar and Identity NFTs
Core NFTs used in LE7EL products. Avatar NFTs can be leveled by burning the experience token.
Getting started
Install Foundry.
Run tests: forge test
Installation
npm i @le7el/core_nfts
JS API
First import the methods you need like: import {utils, availableIdentity, availableAvatar} from '@le7el/core_nfts'
.
For documentation of utils
, please check CRS docs.
avatarAvailable(string name, string chainId, Web3Provider provider = null) returns (boolean promise)
Checks if specific name wasn't registered already.
```js
await avatarAvailable("JohnDoe", "5")
```
identityAvailable(string name, string chainId, Web3Provider provider = null) returns (boolean promise)
The same as avatarAvailable
.
avatarRentPrice(string name, integer duration, string chainId, Web3Provider provider = null) 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 registerAvatar
automatically, call erc20Approve
if there is non-zero fee in ERC20 token.
identityRentPrice(string name, integer duration, string chainId, Web3Provider provider = null) returns ([address, BigNumber] promise)
The same as avatarRentPrice
.
makeAvatarCommitment(string name, address owner, bytes32 secret, string chainId, Web3Provider provider = null) returns (bytes32 promise)
Generates commitment hash for the provided secret.
```js
const owner = "0x0000000000000000000000000000000000000000"
const secret = ethers.utils.randomBytes(32)
const commitment = await makeAvatarCommitment("JohnDoe", "5")
```
makeIdentityCommitment(string name, address owner, bytes32 secret, string chainId, Web3Provider provider = null) returns (bytes32 promise)
The same as makeAvatarCommitment
.
commitAvatar(bytes32 commitment, string chainId, Web3Provider provider = null) returns (transaction promise)
Start registration of CRS name, there should be 60 seconds delay between commitment and registration to prevent race conditions.
```js
await commitAvatar(commitment, "5")
```
commitIdentity(string name, bytes32 commitment, bytes pass, string chainId, Web3Provider provider = null) returns (transaction promise)
Commitment version with whitelisted pass.
```js
await commitIdentity(name, commitment, pass, "5")
```
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 controller.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)
)
```
commitAvatarWhitelisted(string name, bytes32 commitment, bytes pass, string chainId, Web3Provider provider = null) returns (transaction promise)
Commitment version of commitAvatar with whitelisted pass. If avatar controller has enabled commit through Gated controller, then this version of commitAvatar should be used. Read more about how to generate pass in commitIdentity description.
```js
await commitAvatarWhitelisted(name, commitment, pass, "5")
```
registerAvatar(string name, address owner, integer duration, bytes32 secret, string chainId, Web3Provider provider = null) returns (transaction promise)
All variables should be the same as used on makeAvatarCommitment
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 = 31556000 // 1 year in seconds
await registerAvatar("JohnDoe", owner, duration, secret, "5")
```
registerIdentity(string name, address owner, integer duration, bytes32 secret, string chainId, Web3Provider provider = null) returns (transaction promise)
The same as registerAvatar
.
renewAvatar(string name, integer duration, string chainId, Web3Provider provider = null) returns (transaction promise)
Extend rent period for avatar NFT by the number of seconds
```js
const duration = 31536000 // 1 year in seconds
await registerAvatar("JohnDoe", duration, "5")
```
renewIdentity(string name, integer duration, string chainId, Web3Provider provider = null) returns (transaction promise)
The same as renewAvatar
.
getAvatarGasFee(integer duration, string chainId, Web3Provider provider = null) returns (array promise)
Get beneficiary address and fee in gas coin for minting avatar NFT.
```js
await getAvatarGasFee(31536000, "5")
```
getIdentityGasFee(integer duration, string chainId, Web3Provider provider = null) returns (array promise)
The same as getAvatarGasFee
.
getAvatarNameExpires(string name, string chainId, Web3Provider provider = null) returns (BigNumber promise)
Get expire date in timestamp for name registered as CRS record associated with NFT.
```js
await getAvatarNameExpires("JohnDoe", "5")
```
getIdentityNameExpires(string name, string chainId, Web3Provider provider = null) returns (BigNumber promise)
The same as getAvatarNameExpires
.
setText(string node, string key, string value, string chainId, Web3Provider provider = null) returns (transaction promise)
Store text record on-chain, node
can be generated from name or NFT utils.nameToNode('johndoe.l7l')
or utils.idToNode(2871587377811694866171220606258498541438397112258729693763861304963081030941)
. Stored value can be read with getText
for the same node and key.
getText(string node, string key, string chainId, Web3Provider provider = null) 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, Web3Provider provider = null) returns (transaction promise)
Helper to customise on-chain NFT image in metadata.
getNftImage(string node, string chainId, Web3Provider provider = null) returns (string promise)
Read custom NFT image, can be empty if no custom image is stored on-chain. Use getAvatarMetadataByNftId
or getIdentityMetadataByNftId
to get properly resolved image either in image
or image_data
key.
getAvatarNameByNftId(integer id, string chainId, Web3Provider provider = null) 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.l7l')
or utils.nodeToId(0x065942c7a3e13329f007894615b14cf2e9026dc7f015dbd561fbb753c6e5cd1d)
. As with getNftImage
, you get the same data by using getAvatarMetadataByNftId
or getIdentityMetadataByNftId
in a name
key with zone suffix.
getIdentityNameByNftId(integer id, string chainId, Web3Provider provider = null) returns (string promise)
Same as getAvatarNameByNftId
.
getAvatarMetadataByNftId(integer id, string chainId, Web3Provider provider = null) returns (object promise)
Read NFT metadata by id, id
can be generated from name or node as described in getAvatarNameByNftId
.
```json
{
"name":"johndoe.l7l",
"description":"Ownership of identity record on le7el.com",
"image_data":"<svg>...</svg>",
"attributes":[{"trait_type":"Type","value":"Identity"}]
}
```
getIdentityMetadataByNftId(integer id, string chainId, Web3Provider provider = null) returns (object promise)
Same as getAvatarMetadataByNftId
.
getAvatarNftsForWallet(address wallet, string chainId, integer from_block, integer to_block, integer queries_per_batch, Web3Provider provider = null) returns (array promise)
Get array of all NFT ids owned by the wallet
. Be cautious with params, as most RPC allow only 3500-10000 queries per batch. This is heavy operation, so avoid it's usage when possible and cache the results.
getIdentityNftsForWallet(address wallet, string chainId, integer from_block, integer to_block, integer queries_per_batch, Web3Provider provider = null) returns (array promise)
Same as getAvatarNftsForWallet
.
getLe7elExperience(string node, string chainId, Web3Provider provider = null) returns (integer promise)
Get experience points in LE7EL avatar system.
Low-level getProjectExperience(projectNode, node, chainId)
is also available. Generic leveling system will work if you call setProjectLevelingRules
, being an owner of projectNode
.
getLe7elLevel(string node, string chainId, Web3Provider provider = null) returns (integer promise)
Get level in LE7EL avatar system, it may change is leveling formula was changed.
Low-level getProjectLevel(projectNode, node, chainId)
is also available. Generic leveling system will work if you call setProjectLevelingRules
, being an owner of projectNode
.
advanceToNextLe7elLevel(string node, integer experienceToBurn, string chainId, Web3Provider provider = null) returns (integer promise)
Burn experience tokens to advance level in LE7EL avatar system, returns total experience points after the burn.
Low-level advanceToNextLevel(projectNode, node, experienceToBurn, chainId)
is also available, but it doesn't have approval of spending for resolver contract for experience token. Generic leveling system will work if you call setProjectLevelingRules
, being an owner of projectNode
.
Smart contract API
IdentityNFTV1
uses default CRS NFT interface.
IdentityControllerV1
uses default gated controller interface.
AvatarNFTV1
The following API extends CRS NFT interface.
setBasenodeResolverSettings(bytes calldata _callData)
Change the leveling formula or token which is burned to build NFT experience. Use 0
for non ERC1155 tokens. Use address(0)
to use default leveling formula. The following burn interfaces are supported: 0xf5298aca, 0x9dc29fac or 0x79cc6790 (default). _callData
can be generated in a following way:
```
abi.encodeWithSignature(
"changeProjectLevelingRules(address,address,uint256,bytes4)",
levelingFormulaProxy,
experienceToken,
experienceTokenId,
burnInterface
)
```
AvatarControllerV1
The following API extends controller interface.
Deployments
To deploy, run scripts with the relevant environment variables: source .secret && CRS_RESOLVER_ADDRESS=0x0000000000000000000000000000000000000000 CRS_REGISTRY_ADDRESS=0x0000000000000000000000000000000000000000 EXP_TOKEN_ADDRESS=0xc566b9Ce143B73704Ca75AE3e9bDBDC5d069B3cF VIRTUAL_DIST_ADDRESS=0x0000000000000000000000000000000000000000 forge script script/DeployAll.s.sol:DeployAllScript --rpc-url $SEPOLIA_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 contributor NFT with standalone CRS framework, run scripts with the relevant environment variables: source .secret && CRS_RESOLVER_ADDRESS=0x86c5646440bA6D0BfaAF08853BCA4F58528f3327 CRS_REGISTRY_ADDRESS=0x702b0d7B1ae097fB59f4CD8979aec7C06F68c626 EXP_TOKEN_ADDRESS=0x0000000000000000000000000000000000000000 VIRTUAL_DIST_ADDRESS=0x0000000000000000000000000000000000000000 forge script script/DeployContributorAndCRS.s.sol:DeployContributorAndCRSScript --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key $ETHERSCAN_KEY -vvvv --slow
.
To deploy identity metadata proxy: source .secret && IDENTITY_CONTROLLER_ADDRESS=0x7d9F75f2BEC682a134610F92d54ba580A142D9f6 forge script script/DeployIdentityMetadata.s.sol:DeployIdentityMetadataScript --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key $ETHERSCAN_KEY -vvvv --slow
.
To deploy avatar metadata proxy: source .secret && AVATAR_CONTROLLER_ADDRESS=0xb2F44a14f7DbBE0EDbe3D8889a9b538EcF4069Db forge script script/DeployAvatarMetadata.s.sol:DeployAvatarMetadataScript --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key $ETHERSCAN_KEY -vvvv --slow
.
To deploy contributor metadata proxy: source .secret && CONTRIBUTOR_CONTROLLER_ADDRESS=0x8A9eB20C3d193B0909966B7b65fE57a7a2d27496 forge script script/DeployContributorMetadata.s.sol:DeployContributorMetadataScript --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key $ETHERSCAN_KEY -vvvv --slow
.
To change resolver: source .secret && CRS_REGISTRY_ADDRESS=0x4246D62c958D5a8d5C95A6841E70562Bb13F627f IDENTITY_CONTROLLER_ADDRESS=0x7d9F75f2BEC682a134610F92d54ba580A142D9f6 AVATAR_CONTROLLER_ADDRESS=0xb2F44a14f7DbBE0EDbe3D8889a9b538EcF4069Db AVATAR_NFT_ADDRESS=0x8867AaeE03b9e573a300CCa93Af1F79c53262eBf IDENTITY_NFT_ADDRESS=0x3e72fBd0cf67E02e022c71c555A59d4D891832D4 EXP_TOKEN_ADDRESS=0xA0FE716a07be4C0880EA8E8bEae9098D0aF8c32C forge script script/ChangeResolver.s.sol:ChangeResolverScript --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key $ETHERSCAN_KEY -vvvv --slow
.
To deploy investor NFT: source .secret && INVESTOR_OWNER_ADDRESS=0xeeF30c8B265Ffa552781C1f8a5F2CECff3D3a84B INVESTOR_BENEFICIARY_ADDRESS=0xeeF30c8B265Ffa552781C1f8a5F2CECff3D3a84B INITIAL_MERKLE_ROOT=0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 forge script script/DeployInvestor.s.sol:DeployInvestorScript --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key $ETHERSCAN_KEY -vvvv --slow
.
Rinkeby
- Registry:
0xf754b8De91Bd619227B5DF74c760B58048A4095D
- Resolver:
0x29f24ba9813445b48013d13dc7e20b560eadd825
- Identity controller:
0x9434b086fdd4cf118d2288a7257b3dd52b6c754a
- Identity NFT:
0xf02153c5d574bb1bc7f4032280c4989ec451442d
- Avatar controller:
0x1dd23e65617c2ea9cb8b0a8e56e9df9d3f8adbf6
- Avatar NFT:
0x4da49b2e09f7c1ba40626343d4cb97da78414ebc
Goerli
- Registry:
0x4246D62c958D5a8d5C95A6841E70562Bb13F627f
- Resolver:
0x433162aA72a980117aa38A21EC383EFB91cd9374
- Identity controller:
0x7d9F75f2BEC682a134610F92d54ba580A142D9f6
- Identity NFT:
0x3e72fBd0cf67E02e022c71c555A59d4D891832D4
- Avatar controller:
0xb2F44a14f7DbBE0EDbe3D8889a9b538EcF4069Db
- Avatar NFT:
0x8867AaeE03b9e573a300CCa93Af1F79c53262eBf
- Investor NFT:
0xEF15D863F87B95127b1b1E66eAF6C13504643b3E
- Investor NFT minter:
0x8E897DB70C3d7c5daEB0e93BEDbc86CD2AfF38A3
Sepolia
- Registry:
0x702b0d7B1ae097fB59f4CD8979aec7C06F68c626
- Resolver:
0x86c5646440bA6D0BfaAF08853BCA4F58528f3327
- Identity controller:
0x4B08725B4EdD7a41924888204798FFA14e85c41c
- Identity NFT:
0x3C34AF6DDafB21C3A9293F1356E3684bF3d5a1bD
- Avatar controller:
0x5682faA9D58BFfa0d348dc144995bF3DaF9666de
- Avatar NFT:
0xc7F81E795FE8eA3242dF960428E54398C32Aadfc
- Contributor controller:
0x8A9eB20C3d193B0909966B7b65fE57a7a2d27496
- Contributor NFT:
0x68Fe087B98a42620A021AA51BAFAf3cB5952680F
Polygon
- CRS registry:
0xDF4D2C1d3F9B960501deFDBDB9f7D32361E4C72F
- Resolver:
0xc53D1853A87860B8CF9D14dC302A75E6198697B8
- Identity controller:
0xE5Fe2D10697588E34c7aA6902cB51ae7f7562409
- Identity NFT:
0x89915792efC73A098fDfF8F9Cc152524Efcda5AB
- Avatar controller:
0x88C39c7dB366D40154f00644De8c19F98f7C633D
- Avatar NFT:
0xc477144C19bcaec754109B5b96f2046302850cbC
Ethereum
- Investor NFT:
0xf4E28D3F6167D416b1FDC248C82AA59263f52a6d
- Investor NFT minter:
0x4f047dE021cB38f0C6C6b45567658073AC91C605