Asset workflows
The calls that take a T-Deed through its life, in order, with who makes each one. The rules behind
each step are in protocol-overview.md; every function's access and
events are in smart-contracts.md.
On this page
All of these are direct contract calls. The Clear app has no screens for minting, validating, subdividing or fractionalizing T-Deeds, and no service mints them yet.
flowchart TD
A["Minter: mintAsset"] --> B["Owner or validator: set traits"]
B --> C["Validator: validateDeed"]
C -->|"isValidated = false"| B
C -->|"isValidated = true"| D{"Asset type"}
D -->|"Land or Estate"| E["Owner: createSubdivision, mintUnit"]
E --> F["Collection admin: set unit traits"]
F --> G["Validator: validateSubdivisionUnit"]
D -->|"Any type"| H["Owner: createFraction"]
H --> I["Collection admin: mintShares"]
I --> J["Holder of every share: unlockAsset"]Validation is not required before createFraction; the diagram shows the usual order.
1. Before the first mint
An admin has to finish the wiring the deploy script leaves open. The list is in
smart-contracts.md. In short:
- 1.A validator is registered and active in the
ValidatorRegistry, supports the asset type, and has a default operating agreement (validator lifecycle). - 2.If mint fees are charged:
DeedNFT.setFundManager,FundManager.addCompatibleDeedNFT(DeedNFT), and on the validator a whitelisted payment token with a non-zerosetServiceFee. - 3.Validation criteria are set on the validator. Until they are, every deed of a supported type validates.
- 4.The minter holds
MINTER_ROLEonDeedNFT(addMinter).
2. Mint
The minter calls DeedNFT.mintAsset and names the owner.
mintAsset(owner, assetType, uri, definition, configuration, validatorAddress, token, salt)ownerassetType0 Land, 1 Vehicle, 2 Estate, 3 CommercialEquipmenturidefinitiondescriptionconfigurationvalidatorAddresstokenFundManager is setsaltWith a FundManager, the minter (not the owner) pays the validator's service fee, so it approves the
FundManager for that amount of token first. The deed starts with isValidated = false.
Event: DeedNFTMinted.
3. Describe the asset
The details a validator checks are separate traits on the deed. The owner, or a validator,
sets each one with DeedNFT.setTrait:
setTrait(tokenId, bytes("parcelNumber"), bytes("APN 123-456-789"), 1) // 1 = stringUse string values (valueType 1). The trait keys for each asset type are on its page:
land, vehicles,
estates, commercial equipment.
Supporting records go to the MetadataRenderer: manageTokenDocument for documents,
setTokenFeatures, setAssetCondition, setTokenLegalInfo, and the image trait or
setTokenGallery for pictures (metadata-renderer.md).
4. Validate
The validator's operator calls Validator.validateDeed(tokenId). It checks the asset type,
operating agreement, definition and required traits, then writes the result to the deed
(validation-system.md). If the result is
false, fix the traits and call it again.
After this, an owner's updateMetadata sets the deed back to unvalidated; the validator has to run
validateDeed again.
5. Subdivide (Land and Estate)
The deed's owner creates the subdivision and mints units.
- 1.
Subdivide.createSubdivision(deedId, name, description, symbol, collectionUri, totalUnits, burnable). The deed must be validated. The caller becomes the collection admin. - 2.
mintUnit(deedId, unitId, to)orbatchMintUnits(deedId, unitIds, recipients), with unit ids from 0 tototalUnits - 1. - 3.The collection admin sets each unit's own traits with
setUnitTraitFlexible, including every trait the validator's criteria require. Units copy onlyassetType,operatingAgreement,definitionandconfigurationfrom the deed. - 4.The validator's operator calls
Validator.validateSubdivisionUnit(Subdivide, deedId, unitId)for each unit.
Units move with ERC-1155 safeTransferFrom. To close the subdivision, burn every unit
(burnUnit, while burnable), then the deed's owner calls deactivateSubdivision. See
subdivision.md.
6. Fractionalize
The deed's owner locks it in Fractionalize and mints shares against it.
- 1.A
DeedNFTadmin has addedFractionalizeto the approved-marketplace list (setApprovedMarketplace(Fractionalize, true)). Without it, the next two steps revert while royalties are enforced. - 2.The owner calls
DeedNFT.approve(Fractionalize, deedId). - 3.The owner calls
Fractionalize.createFraction(params)withassetTypeDeedNFT, the deed id, a name and symbol,totalShares,burnableand anapprovalPercentageof 51–100. Chooseburnable = true: a non-burnable fraction cannot be unlocked once shares exist. - 4.The owner, now the collection admin, mints with
mintShares(fractionId, amount, to)orbatchMintShares.getFractionToken(fractionId)gives the ERC-20 address.
Subdivision units cannot be fractionalized. See
fractionalization.md.
7. Unlock
Whoever holds every minted share takes the deed back out. Collect all shares in one wallet,
then call Fractionalize.unlockAsset({fractionId, to, checkApprovals: false}). The shares are
burned and the deed goes to to. Before any shares are minted, the collection admin can do the
same.
8. Transfer and burn
- Transfer. The owner can transfer a deed directly. Anyone else moving it, including a marketplace, must be on
DeedNFT's approved-marketplace list while royalties are enforced. Each transfer rewrites thebeneficiarytrait.royaltyInfonames the deed's validator as the royalty receiver. - Burn. The owner calls
burnAsset(tokenId)orburnBatchAssets(tokenIds). The deed's traits are cleared.