Tokenization Precompile API
Every function on the tokenization precompile from abi.json: 25 transactions, executeMultiple, 17 queries, 7 utilities, with signatures and JSON.
Reference for all 50 functions on the tokenization precompile at 0x0000000000000000000000000000000000001001, regenerated from x/tokenization/precompile/abi.json. Each method takes one string calldata msgJson, except executeMultiple and the pure utilities.
Interface
interface ITokenizationPrecompile {
struct MessageInput {
string messageType; // e.g., "createCollection", "transferTokens"
string msgJson; // JSON matching the protobuf format
}
// Transaction methods
function transferTokens(string calldata msgJson) external returns (bool success);
function setIncomingApproval(string calldata msgJson) external returns (bool success);
function setOutgoingApproval(string calldata msgJson) external returns (bool success);
function deleteIncomingApproval(string calldata msgJson) external returns (bool success);
function deleteOutgoingApproval(string calldata msgJson) external returns (bool success);
function updateUserApprovals(string calldata msgJson) external returns (bool success);
function purgeApprovals(string calldata msgJson) external returns (uint256 numPurged);
function createCollection(string calldata msgJson) external returns (uint256 collectionId);
function updateCollection(string calldata msgJson) external returns (uint256 collectionId);
function universalUpdateCollection(string calldata msgJson) external returns (uint256 collectionId);
function deleteCollection(string calldata msgJson) external returns (bool success);
function setValidTokenIds(string calldata msgJson) external returns (uint256 collectionId);
function setManager(string calldata msgJson) external returns (uint256 collectionId);
function setCollectionMetadata(string calldata msgJson) external returns (uint256 collectionId);
function setTokenMetadata(string calldata msgJson) external returns (uint256 collectionId);
function setCustomData(string calldata msgJson) external returns (uint256 collectionId);
function setStandards(string calldata msgJson) external returns (uint256 collectionId);
function setCollectionApprovals(string calldata msgJson) external returns (uint256 collectionId);
function setIsArchived(string calldata msgJson) external returns (uint256 collectionId);
function createDynamicStore(string calldata msgJson) external returns (uint256 storeId);
function updateDynamicStore(string calldata msgJson) external returns (bool success);
function deleteDynamicStore(string calldata msgJson) external returns (bool success);
function setDynamicStoreValue(string calldata msgJson) external returns (bool success);
function createAddressLists(string calldata msgJson) external returns (bool success);
function castVote(string calldata msgJson) external returns (bool success);
function executeMultiple(MessageInput[] calldata messages) external returns (bool success, bytes[] memory results);
// Query methods
function getCollection(string calldata msgJson) external view returns (bytes memory collection);
function getCollectionStats(string calldata msgJson) external view returns (bytes memory stats);
function getBalance(string calldata msgJson) external view returns (bytes memory balance);
function getBalanceAmount(string calldata msgJson) external view returns (uint256 amount);
function getTotalSupply(string calldata msgJson) external view returns (uint256 amount);
function getAddressList(string calldata msgJson) external view returns (bytes memory list);
function getApprovalTracker(string calldata msgJson) external view returns (bytes memory tracker);
function getChallengeTracker(string calldata msgJson) external view returns (uint256 numUsed);
function getETHSignatureTracker(string calldata msgJson) external view returns (uint256 numUsed);
function getDynamicStore(string calldata msgJson) external view returns (bytes memory store);
function getDynamicStoreValue(string calldata msgJson) external view returns (bytes memory value);
function getWrappableBalances(string calldata msgJson) external view returns (uint256 amount);
function isAddressReservedProtocol(string calldata msgJson) external view returns (bool isReserved);
function getAllReservedProtocolAddresses(string calldata msgJson) external view returns (address[] memory addresses);
function getVote(string calldata msgJson) external view returns (bytes memory vote);
function getVotes(string calldata msgJson) external view returns (bytes memory votes);
function params(string calldata msgJson) external view returns (bytes memory params);
// Utility methods (pure)
function convertEvmAddressToBech32(address evmAddress) external pure returns (string memory bech32Address);
function convertBech32ToEvmAddress(string calldata bech32Address) external pure returns (address evmAddress);
function rangeContains(uint256 start, uint256 end, uint256 value) external pure returns (bool contains);
function rangesOverlap(uint256 start1, uint256 end1, uint256 start2, uint256 end2) external pure returns (bool overlap);
function searchInRanges(string calldata rangesJson, uint256 value) external pure returns (bool found);
function getBalanceForIdAndTime(string calldata balancesJson, uint256 tokenId, uint256 time) external pure returns (uint256 amount);
function getReservedListId(address addr) external pure returns (string memory listId);
}The full interface with events and doc comments is contracts/interfaces/ITokenizationPrecompile.sol.
JSON Rules
- The JSON is the protobuf JSON of the
x/tokenizationmessage or query request, decoded with the module codec. Field names are camelCase, exactly as on the message pages. - Numbers are strings (
"123", never123). Booleans are raw (true). Arrays and objects are standard JSON. - Addresses may be
0xhex orbb1bech32. The precompile converts hex to bech32 intoAddresses,manager, approval criteria, address lists, and query address fields. creatoris set frommsg.sender. A value in the JSON is ignored.- Unknown fields, wrong types, and missing required fields revert with code 1. See Errors.
- Invariants and cosmos coin wrapper paths are settable at creation (
createCollectionWithInvariantsJSON); the chain README notes some deeply nested items may be skipped silently on conversion, so verify withgetCollectionafter creation.
Ask your agent:
Build the MsgTransferTokens JSON that sends 1 of token ID 1 in collection 1 from alice to bob, with no prioritized approvals, so I can pass it as msgJson to transferTokens.The bb build transfer command and the MCP builder tools emit the same camelCase JSON the precompile accepts; strip the outer typeUrl/value envelope and the creator field.
Transaction Methods
transferTokens
Transfer tokens from the caller (or from an address that has approved the caller) to one or more recipients. Message: MsgTransferTokens.
function transferTokens(string calldata msgJson) external returns (bool success){
"collectionId": "123",
"transfers": [
{
"from": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
"toAddresses": ["bb1py4mfpg6uf59qkyzg0nmau322c5873eeysp5ue"],
"balances": [
{
"amount": "1000",
"tokenIds": [{"start": "1", "end": "1"}],
"ownershipTimes": [{"start": "1", "end": "18446744073709551615"}]
}
],
"prioritizedApprovals": [],
"onlyCheckPrioritizedCollectionApprovals": false,
"onlyCheckPrioritizedIncomingApprovals": false,
"onlyCheckPrioritizedOutgoingApprovals": false
}
]
}from defaults to the caller. Set it to another address only when that address has granted the contract an outgoing approval. Other Transfer fields (precalculateBalancesFromApproval, merkleProofs, ethSignatureProofs, memo) are accepted as in the message.
Helper (the common single-balance case):
address[] memory recipients = new address[](1);
recipients[0] = 0x092bb4851ae26850588243e7bef22a56287f4739;
string memory json = TokenizationJSONHelpers.transferTokensJSON(
1, // collectionId
recipients, // address[] recipients
1000, // uint256 amount
TokenizationJSONHelpers.uintRangeToJson(1, 1), // tokenIdsJson
TokenizationJSONHelpers.uintRangeToJson(1, TokenizationJSONHelpers.FOREVER) // ownershipTimesJson
);Explicit from and balances with balanceToJson:
string memory balancesJson = TokenizationJSONHelpers.balanceToJson(
amount,
TokenizationJSONHelpers.uintRangeToJson(1, 1), // tokenIds
TokenizationJSONHelpers.uintRangeToJson(1, TokenizationJSONHelpers.FOREVER) // ownershipTimes
);
string memory transferJson = string(abi.encodePacked(
'{"collectionId":"', TokenizationJSONHelpers.uintToString(collectionId),
'","transfers":[{"from":"bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d","toAddresses":["bb1py4mfpg6uf59qkyzg0nmau322c5873eeysp5ue"],',
'"balances":[', balancesJson, ']}]}'
));
bool success = TOKENIZATION.transferTokens(transferJson);Emits precompile_transfer_tokens with collection_id, from, to_addresses, amount, token_ids, ownership_times.
setIncomingApproval
Set or replace one incoming approval on the caller's balance store. Message: MsgSetIncomingApproval.
function setIncomingApproval(string calldata msgJson) external returns (bool success){
"collectionId": "123",
"approval": {
"fromListId": "All",
"initiatedByListId": "All",
"transferTimes": [{"start": "1", "end": "18446744073709551615"}],
"tokenIds": [{"start": "1", "end": "100"}],
"ownershipTimes": [{"start": "1", "end": "18446744073709551615"}],
"approvalId": "accept-all",
"approvalCriteria": {}
}
}Helper: setIncomingApprovalJSON(collectionId, approvalJson); build the approval with userIncomingApprovalToJson. Addresses in approvalCriteria are converted from hex. Emits precompile_set_incoming_approval.
setOutgoingApproval
Set or replace one outgoing approval on the caller's balance store. Message: MsgSetOutgoingApproval.
function setOutgoingApproval(string calldata msgJson) external returns (bool success){
"collectionId": "123",
"approval": {
"toListId": "All",
"initiatedByListId": "bb1t77myv2k0zh7evm87qedj0my9ajpsz4rp7vqsa",
"transferTimes": [{"start": "1", "end": "18446744073709551615"}],
"tokenIds": [{"start": "1", "end": "100"}],
"ownershipTimes": [{"start": "1", "end": "18446744073709551615"}],
"approvalId": "allow-contract",
"approvalCriteria": {}
}
}Helper: setOutgoingApprovalJSON(collectionId, approvalJson) with userOutgoingApprovalToJson. Emits precompile_set_outgoing_approval.
deleteIncomingApproval and deleteOutgoingApproval
Delete an approval by ID. Messages: MsgDeleteIncomingApproval, MsgDeleteOutgoingApproval.
function deleteIncomingApproval(string calldata msgJson) external returns (bool success)
function deleteOutgoingApproval(string calldata msgJson) external returns (bool success){
"collectionId": "123",
"approvalId": "approval-123"
}string memory json = TokenizationJSONHelpers.deleteIncomingApprovalJSON(
collectionId,
approvalId
);
string memory json = TokenizationJSONHelpers.deleteOutgoingApprovalJSON(
collectionId,
approvalId
);updateUserApprovals
Replace the caller's outgoing approvals, incoming approvals, auto-approve flags, and user permissions in one message. Each group has an update* flag. Message: MsgUpdateUserApprovals.
function updateUserApprovals(string calldata msgJson) external returns (bool success){
"collectionId": "123",
"updateOutgoingApprovals": true,
"outgoingApprovals": [],
"updateIncomingApprovals": false,
"incomingApprovals": [],
"updateAutoApproveSelfInitiatedOutgoingTransfers": true,
"autoApproveSelfInitiatedOutgoingTransfers": true,
"updateAutoApproveSelfInitiatedIncomingTransfers": false,
"autoApproveSelfInitiatedIncomingTransfers": true,
"updateAutoApproveAllIncomingTransfers": false,
"autoApproveAllIncomingTransfers": false,
"updateUserPermissions": false,
"userPermissions": {}
}Helper: updateUserApprovalsJSON(collectionId, updateOutgoingApprovals, outgoingApprovalsJson, updateIncomingApprovals, incomingApprovalsJson, updateAutoApproveSelfInitiatedOutgoingTransfers, autoApproveSelfInitiatedOutgoingTransfers, updateAutoApproveSelfInitiatedIncomingTransfers, autoApproveSelfInitiatedIncomingTransfers, updateAutoApproveAllIncomingTransfers, autoApproveAllIncomingTransfers, updateUserPermissions, userPermissionsJson).
purgeApprovals
Remove expired approvals, or counterparty approvals that name the caller, from a balance store. Returns the number purged. Message: MsgPurgeApprovals.
function purgeApprovals(string calldata msgJson) external returns (uint256 numPurged){
"collectionId": "123",
"purgeExpired": true,
"approverAddress": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
"purgeCounterpartyApprovals": false,
"approvalsToPurge": []
}Helper: purgeApprovalsJSON(collectionId, purgeExpired, approverAddress, purgeCounterpartyApprovals, approvalsToPurgeJson).
createCollection
Create a collection. The caller becomes the creator; manager may be any address. Returns the new collection ID. Message: MsgCreateCollection.
function createCollection(string calldata msgJson) external returns (uint256 collectionId){
"validTokenIds": [{"start": "1", "end": "1000"}],
"manager": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
"collectionMetadata": {
"uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json",
"customData": "{\"name\":\"My Token\"}"
},
"defaultBalances": {
"autoApproveSelfInitiatedOutgoingTransfers": true,
"autoApproveSelfInitiatedIncomingTransfers": true
},
"standards": ["ERC-3643"]
}{
"validTokenIds": [{"start": "1", "end": "1000"}],
"manager": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
"collectionMetadata": {
"uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json",
"customData": "{\"name\":\"My Token\"}"
},
"defaultBalances": {
"balances": [],
"outgoingApprovals": [],
"incomingApprovals": [],
"autoApproveSelfInitiatedOutgoingTransfers": true,
"autoApproveSelfInitiatedIncomingTransfers": true,
"autoApproveAllIncomingTransfers": false,
"userPermissions": {
"canUpdateOutgoingApprovals": [],
"canUpdateIncomingApprovals": [],
"canUpdateAutoApproveSelfInitiatedOutgoingTransfers": [],
"canUpdateAutoApproveSelfInitiatedIncomingTransfers": [],
"canUpdateAutoApproveAllIncomingTransfers": []
}
},
"standards": ["ERC-3643"],
"isArchived": false
}Other accepted fields: collectionPermissions, tokenMetadata, customData, collectionApprovals, mintEscrowCoinsToTransfer, cosmosCoinWrapperPathsToAdd, invariants, aliasPathsToAdd.
string memory json = TokenizationJSONHelpers.createCollectionJSON(
validTokenIdsJson, // Use uintRangeToJson or uintRangeArrayToJson
manager, // address string (0x or bb1)
collectionMetadataJson, // Use collectionMetadataToJson
defaultBalancesJson, // Use simpleUserBalanceStoreToJson or custom JSON
collectionPermissionsJson, // "{}" for empty
standardsJson, // Use stringArrayToJson
customData, // Optional string
isArchived // bool
);string memory validTokenIdsJson = TokenizationJSONHelpers.uintRangeToJson(1, 1000);
string memory metadataJson = TokenizationJSONHelpers.collectionMetadataToJson(
"ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json",
"{\"name\":\"My Token\"}"
);
string memory defaultBalancesJson = TokenizationJSONHelpers.simpleUserBalanceStoreToJson(
true, true, false
);
string[] memory standards = new string[](1);
standards[0] = "ERC-3643";
string memory standardsJson = TokenizationJSONHelpers.stringArrayToJson(standards);
string memory createJson = TokenizationJSONHelpers.createCollectionJSON(
validTokenIdsJson,
TokenizationJSONHelpers.addressToString(address(this)),
metadataJson,
defaultBalancesJson,
"{}",
standardsJson,
"",
false
);
uint256 collectionId = TOKENIZATION.createCollection(createJson);Emits CollectionCreated.
updateCollection
Update the fields of a collection that the caller (the manager) is permitted to change. Each field has an update* flag. Returns the collection ID. Message: MsgUpdateCollection.
function updateCollection(string calldata msgJson) external returns (uint256 collectionId){
"collectionId": "123",
"updateCollectionMetadata": true,
"collectionMetadata": {"uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json", "customData": ""},
"updateManager": false,
"updateValidTokenIds": false,
"updateCollectionPermissions": false,
"updateTokenMetadata": false,
"updateCustomData": false,
"updateCollectionApprovals": false,
"updateStandards": false,
"updateIsArchived": false
}Emits CollectionUpdated.
universalUpdateCollection
The superset message: create (collectionId "0") or update a collection, with defaultBalances and every update* flag from updateCollection. Returns the collection ID. Message: MsgUniversalUpdateCollection.
function universalUpdateCollection(string calldata msgJson) external returns (uint256 collectionId){
"collectionId": "0",
"defaultBalances": {
"autoApproveSelfInitiatedOutgoingTransfers": true,
"autoApproveSelfInitiatedIncomingTransfers": true
},
"updateValidTokenIds": true,
"validTokenIds": [{"start": "1", "end": "100"}],
"updateManager": true,
"manager": "0x0bc63cfe31d5218eb414b142c799e20964a54a1a",
"updateCollectionMetadata": true,
"collectionMetadata": {"uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json", "customData": ""}
}{
"collectionId": "0",
"defaultBalances": {
"balances": [],
"outgoingApprovals": [],
"incomingApprovals": [],
"autoApproveSelfInitiatedOutgoingTransfers": true,
"autoApproveSelfInitiatedIncomingTransfers": true,
"autoApproveAllIncomingTransfers": false,
"userPermissions": {
"canUpdateOutgoingApprovals": [],
"canUpdateIncomingApprovals": [],
"canUpdateAutoApproveSelfInitiatedOutgoingTransfers": [],
"canUpdateAutoApproveSelfInitiatedIncomingTransfers": [],
"canUpdateAutoApproveAllIncomingTransfers": []
}
},
"updateValidTokenIds": true,
"validTokenIds": [{"start": "1", "end": "100"}],
"updateManager": true,
"manager": "0x0bc63cfe31d5218eb414b142c799e20964a54a1a",
"updateCollectionMetadata": true,
"collectionMetadata": {"uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json", "customData": ""},
"updateCollectionPermissions": false,
"updateTokenMetadata": false,
"updateCustomData": false,
"updateCollectionApprovals": false,
"updateStandards": false,
"updateIsArchived": false
}deleteCollection
Delete a collection. Only the manager with the canDeleteCollection permission can delete. Message: MsgDeleteCollection.
function deleteCollection(string calldata msgJson) external returns (bool success){
"collectionId": "123"
}string memory json = TokenizationJSONHelpers.deleteCollectionJSON(collectionId);Emits CollectionDeleted.
setValidTokenIds
Set the collection's valid token ID ranges and, optionally, lock the permission. Returns the collection ID. Message: MsgSetValidTokenIds.
function setValidTokenIds(string calldata msgJson) external returns (uint256 collectionId){
"collectionId": "123",
"validTokenIds": [{"start": "1", "end": "2000"}],
"canUpdateValidTokenIds": []
}Helper: setValidTokenIdsJSON(collectionId, validTokenIdsJson, canUpdateValidTokenIdsJson).
setManager
Transfer the manager role. Returns the collection ID. Message: MsgSetManager.
function setManager(string calldata msgJson) external returns (uint256 collectionId){
"collectionId": "123",
"manager": "0x0bc63cfe31d5218eb414b142c799e20964a54a1a",
"canUpdateManager": []
}Helper: setManagerJSON(collectionId, manager, canUpdateManagerJson). The hex manager address is converted to bech32.
setCollectionMetadata
Set the collection metadata (uri, customData). Returns the collection ID. Message: MsgSetCollectionMetadata.
function setCollectionMetadata(string calldata msgJson) external returns (uint256 collectionId){
"collectionId": "123",
"collectionMetadata": {"uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json", "customData": ""},
"canUpdateCollectionMetadata": []
}Helper: setCollectionMetadataJSON(collectionId, collectionMetadataJson, canUpdateCollectionMetadataJson). URIs and customData are capped at 10,000 characters.
setTokenMetadata
Set per-token-ID metadata. Returns the collection ID. Message: MsgSetTokenMetadata.
function setTokenMetadata(string calldata msgJson) external returns (uint256 collectionId){
"collectionId": "123",
"tokenMetadata": [
{"uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/{id}.json", "customData": "", "tokenIds": [{"start": "1", "end": "100"}]}
],
"canUpdateTokenMetadata": []
}Helper: setTokenMetadataJSON(collectionId, tokenMetadataJson, canUpdateTokenMetadataJson) with tokenMetadataToJson(uri, customData).
setCustomData
Set the collection's customData string. Returns the collection ID. Message: MsgSetCustomData.
function setCustomData(string calldata msgJson) external returns (uint256 collectionId){
"collectionId": "123",
"customData": "{\"symbol\":\"MYT\"}",
"canUpdateCustomData": []
}Helper: setCustomDataJSON(collectionId, customData, canUpdateCustomDataJson).
setStandards
Set the collection's standards list. Returns the collection ID. Message: MsgSetStandards.
function setStandards(string calldata msgJson) external returns (uint256 collectionId){
"collectionId": "123",
"standards": ["ERC-3643"],
"canUpdateStandards": []
}Helper: setStandardsJSON(collectionId, standardsJson, canUpdateStandardsJson).
setCollectionApprovals
Replace the collection-level approvals. Returns the collection ID. Message: MsgSetCollectionApprovals.
function setCollectionApprovals(string calldata msgJson) external returns (uint256 collectionId){
"collectionId": "123",
"collectionApprovals": [
{
"fromListId": "Mint",
"toListId": "All",
"initiatedByListId": "bb1t77myv2k0zh7evm87qedj0my9ajpsz4rp7vqsa",
"transferTimes": [{"start": "1", "end": "18446744073709551615"}],
"tokenIds": [{"start": "1", "end": "100"}],
"ownershipTimes": [{"start": "1", "end": "18446744073709551615"}],
"approvalId": "mint-by-contract",
"approvalCriteria": {"overridesFromOutgoingApprovals": true}
}
],
"canUpdateCollectionApprovals": []
}Helper: setCollectionApprovalsJSON(collectionId, collectionApprovalsJson, canUpdateCollectionApprovalsJson) with collectionApprovalToJson and collectionApprovalArrayToJson. Hex addresses inside approvals and criteria are converted. Criteria reference: Approval Criteria.
setIsArchived
Archive or unarchive a collection. Returns the collection ID. Message: MsgSetIsArchived.
function setIsArchived(string calldata msgJson) external returns (uint256 collectionId){
"collectionId": "123",
"isArchived": false,
"canArchiveCollection": []
}Helper: setIsArchivedJSON(collectionId, isArchived, canArchiveCollectionJson).
createDynamicStore
Create a dynamic boolean store (for example a KYC registry). Returns the store ID. Message: MsgCreateDynamicStore.
function createDynamicStore(string calldata msgJson) external returns (uint256 storeId){
"defaultValue": false,
"uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json",
"customData": "{\"type\":\"kyc\"}"
}string memory json = TokenizationJSONHelpers.createDynamicStoreJSON(
defaultValue, // bool
uri, // string
customData // string
);string memory createJson = TokenizationJSONHelpers.createDynamicStoreJSON(
false,
"ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json",
"{\"type\":\"kyc\"}"
);
uint256 storeId = TOKENIZATION.createDynamicStore(createJson);Emits DynamicStoreCreated.
updateDynamicStore
Update a store's default value, global enabled flag, or metadata. Only the store creator may update. Message: MsgUpdateDynamicStore.
function updateDynamicStore(string calldata msgJson) external returns (bool success){
"storeId": "123",
"defaultValue": false,
"globalEnabled": true,
"uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json",
"customData": ""
}Helper: updateDynamicStoreJSON(storeId, defaultValue, globalEnabled, uri, customData).
deleteDynamicStore
Delete a store. Only the creator may delete. Message: MsgDeleteDynamicStore.
function deleteDynamicStore(string calldata msgJson) external returns (bool success){
"storeId": "123"
}Helper: deleteDynamicStoreJSON(storeId).
setDynamicStoreValue
Set the boolean for an address in a store. Only the creator may set. Message: MsgSetDynamicStoreValue.
function setDynamicStoreValue(string calldata msgJson) external returns (bool success){
"storeId": "123",
"address": "0x0bc63cfe31d5218eb414b142c799e20964a54a1a",
"value": true
}string memory json = TokenizationJSONHelpers.setDynamicStoreValueJSON(
storeId, // uint256
address_, // address
value // bool
);string memory setValueJson = TokenizationJSONHelpers.setDynamicStoreValueJSON(
kycRegistryId,
user,
true
);
TOKENIZATION.setDynamicStoreValue(setValueJson);createAddressLists
Create one or more address lists. Message: MsgCreateAddressLists.
function createAddressLists(string calldata msgJson) external returns (bool success){
"addressLists": [
{
"listId": "my-allowlist",
"addresses": ["0x0bc63cfe31d5218eb414b142c799e20964a54a1a", "bb1py4mfpg6uf59qkyzg0nmau322c5873eeysp5ue"],
"whitelist": true,
"uri": "",
"customData": ""
}
]
}Helper: createAddressListsJSON(addressListsJson) with addressListInputToJson(listId, addressesJson, whitelist, uri, customData). At most 1,000 addresses per list. Emits AddressListsCreated. Concept: Address Lists.
castVote
Cast a vote on a voting challenge attached to an approval. Message: MsgCastVote.
function castVote(string calldata msgJson) external returns (bool success){
"collectionId": "123",
"approvalLevel": "collection",
"approverAddress": "",
"approvalId": "gated-transfer",
"proposalId": "proposal-1",
"yesWeight": "1"
}Helper: castVoteJSON(collectionId, approvalLevel, approverAddress, approvalId, proposalId, yesWeight). Criteria: Voting Challenges.
executeMultiple
Run several transaction messages in order, atomically, in one call.
function executeMultiple(MessageInput[] calldata messages) external returns (bool success, bytes[] memory results)struct MessageInput {
string messageType; // Method name: "createCollection", "transferTokens", ...
string msgJson; // JSON for that method
}ITokenizationPrecompile.MessageInput[] memory messages = new ITokenizationPrecompile.MessageInput[](2);
// Message 1: Create Collection
string[] memory standards = new string[](0);
string memory createJson = TokenizationJSONHelpers.createCollectionJSON(
TokenizationJSONHelpers.uintRangeToJson(1, 1000),
TokenizationJSONHelpers.addressToString(address(this)),
TokenizationJSONHelpers.collectionMetadataToJson("ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json", ""),
TokenizationJSONHelpers.simpleUserBalanceStoreToJson(true, true, false),
"{}",
TokenizationJSONHelpers.stringArrayToJson(standards),
"",
false
);
messages[0] = ITokenizationPrecompile.MessageInput({
messageType: "createCollection",
msgJson: createJson
});
// Message 2: Transfer Tokens (using collectionId = 0 for auto-prev)
address[] memory recipients = new address[](1);
recipients[0] = 0x092bb4851ae26850588243e7bef22a56287f4739;
string memory transferJson = TokenizationJSONHelpers.transferTokensJSON(
0, // collectionId = 0 means "use previous collection" (auto-prev)
recipients,
1,
TokenizationJSONHelpers.uintRangeToJson(1, 1),
TokenizationJSONHelpers.uintRangeToJson(1, TokenizationJSONHelpers.FOREVER)
);
messages[1] = ITokenizationPrecompile.MessageInput({
messageType: "transferTokens",
msgJson: transferJson
});
// Execute both messages atomically
(bool success, bytes[] memory results) = TOKENIZATION.executeMultiple(messages);
require(success, "Multi-message execution failed");
// Decode results
uint256 collectionId = abi.decode(results[0], (uint256));
bool transferSuccess = abi.decode(results[1], (bool));Behavior:
- Every transaction method name is a valid
messageType. - Atomic: any failure reverts the whole batch. The error names the failing index and type.
- Sequential, in array order. At most 50 messages (
MaxMessagesPerBatch). collectionId: "0"refers to the collection created earlier in the same transaction (the module's auto-prev rule,resolveCollectionIdWithAutoPrev).- Each result is ABI-encoded like the method's own return:
abi.decode(results[i], (bool))or(uint256). - Gas: 10,000 base + 1,000 per message + 100 per 32-byte input chunk, then the transaction buffer. See Gas.
Query Methods
Most getters return the protobuf-encoded gRPC response as bytes. See Return values for how to use them. The request JSON is the query request type from the queries reference; 0x addresses are converted.
getCollection
Query: GetCollection.
function getCollection(string calldata msgJson) external view returns (bytes memory collection){
"collectionId": "123"
}string memory json = TokenizationJSONHelpers.getCollectionJSON(collectionId);string memory queryJson = TokenizationJSONHelpers.getCollectionJSON(collectionId);
bytes memory collection = TOKENIZATION.getCollection(queryJson);
// Protobuf-encoded QueryGetCollectionResponse; decode off-chaingetCollectionStats
Holder count and circulating supply. Query: GetCollectionStats.
function getCollectionStats(string calldata msgJson) external view returns (bytes memory stats){
"collectionId": "123"
}| Field | Type | Description |
|---|---|---|
collectionId | string | Collection ID (uint as string) |
string memory queryJson = string(abi.encodePacked(
'{"collectionId":"', TokenizationJSONHelpers.uintToString(collectionId), '"}'
));
bytes memory stats = TOKENIZATION.getCollectionStats(queryJson);
uint256 holders = TokenizationDecoders.parseHolderCountFromStats(stats);parseHolderCountFromStats reads the holder count from the protobuf bytes on-chain. contracts/test/MaxUniqueHoldersChecker.sol uses it to enforce a holder cap as an invariant.
getBalance
The full balance store for an address: balances, approvals, permissions. Query: GetBalance.
function getBalance(string calldata msgJson) external view returns (bytes memory balance){
"collectionId": "123",
"address": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d"
}userAddress is accepted as an alias of address. Helper: getBalanceJSON(collectionId, userAddress). For an amount, use getBalanceAmount instead.
getBalanceAmount
The amount held for one (tokenId, ownershipTime) pair. Returns uint256 directly. For range queries, use getBalance and process the store off-chain, or pass the balances JSON through getBalanceForIdAndTime.
function getBalanceAmount(string calldata msgJson) external view returns (uint256 amount){
"collectionId": "123",
"address": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
"tokenId": "1",
"ownershipTime": "1609459200000"
}| Field | Type | Description |
|---|---|---|
collectionId | string | Collection ID (uint as string) |
address | string | User address (bech32 or 0x hex) |
tokenId | string | Single token ID to query (uint as string) |
ownershipTime | string | Single ownership time to query (uint as string, typically a ms timestamp) |
// Build JSON manually or use a helper
string memory balanceJson = string(abi.encodePacked(
'{"collectionId":"', TokenizationJSONHelpers.uintToString(collectionId),
'","address":"', TokenizationJSONHelpers.addressToString(userAddress),
'","tokenId":"', TokenizationJSONHelpers.uintToString(tokenId),
'","ownershipTime":"', TokenizationJSONHelpers.uintToString(block.timestamp * 1000),
'"}'
));
uint256 balance = TOKENIZATION.getBalanceAmount(balanceJson);Helper: getBalanceAmountJSON(collectionId, userAddress, tokenId, ownershipTime). Emits precompile_get_balance_amount. Reverts with code 7 if the amount exceeds uint256.
getTotalSupply
Total minted supply for one (tokenId, ownershipTime) pair. Returns uint256.
function getTotalSupply(string calldata msgJson) external view returns (uint256 amount){
"collectionId": "123",
"tokenId": "1",
"ownershipTime": "1609459200000"
}| Field | Type | Description |
|---|---|---|
collectionId | string | Collection ID (uint as string) |
tokenId | string | Single token ID to query (uint as string) |
ownershipTime | string | Single ownership time to query (uint as string, typically a ms timestamp) |
string memory supplyJson = string(abi.encodePacked(
'{"collectionId":"', TokenizationJSONHelpers.uintToString(collectionId),
'","tokenId":"', TokenizationJSONHelpers.uintToString(tokenId),
'","ownershipTime":"', TokenizationJSONHelpers.uintToString(block.timestamp * 1000),
'"}'
));
uint256 supply = TOKENIZATION.getTotalSupply(supplyJson);Helper: getTotalSupplyJSON(collectionId, tokenId, ownershipTime). Concept: Minting and Supply.
getAddressList
Query: GetAddressList.
function getAddressList(string calldata msgJson) external view returns (bytes memory list){
"listId": "my-list-id"
}string memory json = TokenizationJSONHelpers.getAddressListJSON(listId);getApprovalTracker
Tallied amounts and transfer counts for an approval tracker. Query: GetApprovalTracker.
function getApprovalTracker(string calldata msgJson) external view returns (bytes memory tracker){
"collectionId": "123",
"approvalLevel": "collection",
"approverAddress": "",
"approvalId": "mint",
"amountTrackerId": "mint",
"trackerType": "overall",
"approvedAddress": ""
}Helper: getApprovalTrackerJSON(collectionId, approvalLevel, approverAddress, approvalId, trackerType, trackedAddress) (it reuses approvalId as the amountTrackerId). approverAddress and approvedAddress accept hex. Criteria: Approval Trackers.
getChallengeTracker
How many times a merkle challenge leaf has been used. Returns uint256. Query: GetChallengeTracker.
function getChallengeTracker(string calldata msgJson) external view returns (uint256 numUsed){
"collectionId": "123",
"approvalLevel": "collection",
"approverAddress": "",
"approvalId": "claim",
"challengeTrackerId": "claim",
"leafIndex": "0"
}Helper: getChallengeTrackerJSON(collectionId, approvalLevel, approverAddress, approvalId, challengeId, leafIndex). Criteria: Merkle Challenges.
getETHSignatureTracker
How many times an ETH signature has been used against an approval. Returns uint256. Query: GetETHSignatureTracker.
function getETHSignatureTracker(string calldata msgJson) external view returns (uint256 numUsed){
"collectionId": "123",
"approvalLevel": "collection",
"approverAddress": "",
"approvalId": "signed-claim",
"challengeTrackerId": "signed-claim",
"signature": "0xdbcfa79865ccab596d4e5fbc06e34ba09befd01cfd833a73427bd38d5cab2e77dcdbfee5f745b5b082bd17b9ae41a3cffb160ee9343fd777de4a3fbd682397301b"
}Criteria: ETH Signature Challenges.
getDynamicStore
Store configuration: creator, default value, global enabled flag, metadata. Query: GetDynamicStore.
function getDynamicStore(string calldata msgJson) external view returns (bytes memory store){
"storeId": "123"
}Helper: getDynamicStoreJSON(storeId).
getDynamicStoreValue
The boolean for an address in a store, as protobuf bytes. Query: GetDynamicStoreValue.
function getDynamicStoreValue(string calldata msgJson) external view returns (bytes memory value){
"storeId": "123",
"address": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d"
}string memory json = TokenizationJSONHelpers.getDynamicStoreValueJSON(
storeId,
userAddress
);string memory getValueJson = TokenizationJSONHelpers.getDynamicStoreValueJSON(
kycRegistryId,
user
);
bytes memory result = TOKENIZATION.getDynamicStoreValue(getValueJson);
// Protobuf-encoded QueryGetDynamicStoreValueResponse. Decode off-chain, or
// enforce the store on-chain with a dynamic store challenge instead.userAddress is accepted as an alias of address.
getWrappableBalances
How much of a wrapped denom the address can unwrap back into collection tokens. Returns uint256. Query: GetWrappableBalances.
function getWrappableBalances(string calldata msgJson) external view returns (uint256 amount){
"denom": "badges:1:utoken",
"address": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d"
}Helper: getWrappableBalancesJSON(denom, address). Concept: Cosmos Coin Wrapper Paths.
isAddressReservedProtocol
Whether an address is a reserved protocol address. Returns bool. The zero address returns false. Query: IsAddressReservedProtocol.
function isAddressReservedProtocol(string calldata msgJson) external view returns (bool isReserved){
"address": "0x0bc63cfe31d5218eb414b142c799e20964a54a1a"
}Helper: isAddressReservedProtocolJSON(address).
getAllReservedProtocolAddresses
All reserved protocol addresses, returned as EVM addresses. Query: GetAllReservedProtocolAddresses.
function getAllReservedProtocolAddresses(string calldata msgJson) external view returns (address[] memory addresses){}Helper: getAllReservedProtocolAddressesJSON(). Pass "{}" or an empty string.
getVote
One voter's vote on a proposal. Query: GetVote.
function getVote(string calldata msgJson) external view returns (bytes memory vote){
"collectionId": "123",
"approvalLevel": "collection",
"approverAddress": "",
"approvalId": "gated-transfer",
"proposalId": "proposal-1",
"voterAddress": "bb1zc268nctj8xwslgw7q22cahs6k4y048agr6fvf"
}Helper: getVoteJSON(collectionId, approvalLevel, approverAddress, approvalId, proposalId, voterAddress).
getVotes
All votes on a proposal. Query: GetVotes.
function getVotes(string calldata msgJson) external view returns (bytes memory votes){
"collectionId": "123",
"approvalLevel": "collection",
"approverAddress": "",
"approvalId": "gated-transfer",
"proposalId": "proposal-1"
}Helper: getVotesJSON(collectionId, approvalLevel, approverAddress, approvalId, proposalId).
params
Module parameters. Query: Params.
function params(string calldata msgJson) external view returns (bytes memory params){}Helper: paramsJSON(). Also the cheapest connectivity check: precompile.params("{}").
Utility Methods
Pure functions with no state access.
convertEvmAddressToBech32
function convertEvmAddressToBech32(address evmAddress) external pure returns (string memory bech32Address)string memory bech32 = TOKENIZATION.convertEvmAddressToBech32(0x0bc63cfe31d5218eb414b142c799e20964a54a1a);
// Returns: "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d"convertBech32ToEvmAddress
function convertBech32ToEvmAddress(string calldata bech32Address) external pure returns (address evmAddress)address evm = TOKENIZATION.convertBech32ToEvmAddress("bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d");
// Returns: 0x0bc63cfe31d5218eb414b142c799e20964a54a1arangeContains
Inclusive check.
function rangeContains(uint256 start, uint256 end, uint256 value) external pure returns (bool contains)bool isInRange = TOKENIZATION.rangeContains(10, 20, 15);
// Returns: true (15 is in [10, 20])
bool notInRange = TOKENIZATION.rangeContains(10, 20, 25);
// Returns: false (25 is not in [10, 20])rangesOverlap
function rangesOverlap(uint256 start1, uint256 end1, uint256 start2, uint256 end2) external pure returns (bool overlap)bool overlap = TOKENIZATION.rangesOverlap(10, 20, 15, 25);
// Returns: true (ranges [10,20] and [15,25] overlap)
bool noOverlap = TOKENIZATION.rangesOverlap(10, 20, 25, 35);
// Returns: false (ranges [10,20] and [25,35] don't overlap)searchInRanges
Whether a value falls inside any range of a JSON range array.
function searchInRanges(string calldata rangesJson, uint256 value) external pure returns (bool found)string memory rangesJson = '[{"start":"1","end":"100"},{"start":"200","end":"300"}]';
bool found = TOKENIZATION.searchInRanges(rangesJson, 50);
// Returns: true (50 is in [1,100])
bool notFound = TOKENIZATION.searchInRanges(rangesJson, 150);
// Returns: false (150 is not in any range)getBalanceForIdAndTime
The amount for a token ID and time inside a JSON balances array. Useful for balances you obtained off-chain or built yourself. This pure helper parses the legacy badgeIds key for the token ID ranges (the handler in precompile.go reads badgeIds, not tokenIds).
function getBalanceForIdAndTime(string calldata balancesJson, uint256 tokenId, uint256 time) external pure returns (uint256 amount)string memory balancesJson = '[{"amount":"100","badgeIds":[{"start":"1","end":"10"}],"ownershipTimes":[{"start":"0","end":"18446744073709551615"}]}]';
uint256 amount = TOKENIZATION.getBalanceForIdAndTime(balancesJson, 5, block.timestamp * 1000);
// Returns: 100 (token ID 5 is in range [1,10] and time is in [0, max])
uint256 notFound = TOKENIZATION.getBalanceForIdAndTime(balancesJson, 15, block.timestamp * 1000);
// Returns: 0 (token ID 15 is not in any range)getReservedListId
The reserved address list ID for an address, which is its bech32 form. Every address has an implicit list containing only itself.
function getReservedListId(address addr) external pure returns (string memory listId)string memory listId = TOKENIZATION.getReservedListId(0x0bc63cfe31d5218eb414b142c799e20964a54a1a);
// Returns: "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d" (the bech32 address)To test whether a list ID is "All", compare the string: keccak256(bytes(listId)) == keccak256(bytes("All")). Reserved IDs: Address Lists.
Helper Library Reference
Building blocks in TokenizationJSONHelpers:
string memory json = TokenizationJSONHelpers.uintRangeToJson(1, 100);
// Returns: [{"start":"1","end":"100"}]uint256[] memory starts = new uint256[](2);
uint256[] memory ends = new uint256[](2);
starts[0] = 1; ends[0] = 100;
starts[1] = 200; ends[1] = 300;
string memory json = TokenizationJSONHelpers.uintRangeArrayToJson(starts, ends);
// Returns: [{"start":"1","end":"100"},{"start":"200","end":"300"}]string memory json = TokenizationJSONHelpers.collectionMetadataToJson(
"ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json",
"{\"name\":\"My Token\"}"
);string memory json = TokenizationJSONHelpers.simpleUserBalanceStoreToJson(
true, // autoApproveSelfInitiatedOutgoingTransfers
true, // autoApproveSelfInitiatedIncomingTransfers
false // autoApproveAllIncomingTransfers
);string[] memory standards = new string[](2);
standards[0] = "ERC-3643";
standards[1] = "Security Token";
string memory json = TokenizationJSONHelpers.stringArrayToJson(standards);
// Returns: ["ERC-3643","Security Token"]string memory str = TokenizationJSONHelpers.uintToString(123);
// Returns: "123"Further builders: balanceToJson, balanceArrayToJson, tokenMetadataToJson, collectionApprovalToJson, userOutgoingApprovalToJson, userIncomingApprovalToJson, collectionPermissionsToJson, userPermissionsToJson, evmQueryChallengeToJson, collectionInvariantsToJson, cosmosCoinWrapperPathToJson, aliasPathToJson, denomUnitToJson, addressListInputToJson, approvalIdentifierDetailsToJson. Source: TokenizationJSONHelpers.sol.
Events
The precompile emits Cosmos events (precompile_transfer_tokens, precompile_set_incoming_approval, precompile_set_outgoing_approval, precompile_get_balance_amount) with module=evm_precompile. The Solidity interface declares the matching EVM events TransferTokens, SetIncomingApproval, SetOutgoingApproval, CollectionCreated, CollectionUpdated, CollectionDeleted, AddressListsCreated, DynamicStoreCreated. The module's own events are emitted too; see WebSocket Events.