Schema Management
Example
Example of Assets with Schemas
Here we will use party bears (collectionId 303204 on Porcini) as an example to create schemas, and then equip the party bear dynamically through the schema.
Schema Creation
https://ar-docs.futureverse.dev/schema/
Copy
Ask AI
const namespace = "http://schema.futureverse.dev/pb" as NamespaceUrl;
const bearSchema = `
@prefix this: <http://schema.futureverse.dev/pb>.
@prefix sh: <http://www.w3.org/ns/shacl#>.
@prefix fvp: <http://schema.futureverse.com/#>.
@prefix path: <http://schema.futureverse.com/path#>.
this:Bear a fvp:OnChainERC721Asset;
sh:property [
sh:minCount 0;
sh:maxCount 1;
sh:class this:AccessoryEars;
sh:path path:equippedWith_accessoryEars
], [
sh:minCount 0;
sh:maxCount 1;
sh:class this:AccessoryEyewear;
sh:path path:equippedWith_accessoryEyewear
].
`;
const accessoryEyewearSchema = `
@prefix this: <http://schema.futureverse.dev/pb> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix fvp: <http://schema.futureverse.com/#> .
@prefix path: <http://schema.futureverse.com/path#> .
this:AccessoryEyewear a fvp:OnChainERC721Asset ;
.
`;
const accessoryEarsSchema = `
@prefix this: <http://schema.futureverse.dev/pb> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix fvp: <http://schema.futureverse.com/#> .
@prefix path: <http://schema.futureverse.com/path#> .
this:AccessoryEars a fvp:OnChainERC721Asset ;
.
`;
const SchemaCreation = () => {
const { createAsync: createSchemaAsync } = useCreateSchema();
const createPartybearSchema = async () => {
await createSchemaAsync({
name: "bear",
schema: bearSchema,
version: 0,
namespace,
});
};
const createAccessoryEyewearSchema = async () => {
await createSchemaAsync({
name: "accessoryEyewear",
schema: accessoryEyewearSchema,
version: 0,
namespace,
});
};
const createAccessoryEarsSchema = async () => {
await createSchemaAsync({
name: "AccessoryEars",
schema: accessoryEarsSchema,
version: 0,
namespace,
});
};
return (
<div>
<button onClick={createPartybearSchema}>Create Partybear Schema</button>
<button onClick={createAccessoryEyewearSchema}>Create AccessoryEyewear Schema</button>
<button onClick={createAccessoryEarsSchema}>Create AccessoryEars Schema</button>
</div>
);
};
Copy
Ask AI
const namespace = "http://schema.futureverse.dev/pb" as NamespaceUrl;
const bearSchema = `
@prefix this: <http://schema.futureverse.dev/pb>.
@prefix sh: <http://www.w3.org/ns/shacl#>.
@prefix fvp: <http://schema.futureverse.com/#>.
@prefix path: <http://schema.futureverse.com/path#>.
this:Bear a fvp:OnChainERC721Asset;
sh:property [
sh:minCount 0;
sh:maxCount 1;
sh:class this:AccessoryEars;
sh:path path:equippedWith_accessoryEars
], [
sh:minCount 0;
sh:maxCount 1;
sh:class this:AccessoryEyewear;
sh:path path:equippedWith_accessoryEyewear
].
`;
const accessoryEyewearSchema = `
@prefix this: <http://schema.futureverse.dev/pb> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix fvp: <http://schema.futureverse.com/#> .
@prefix path: <http://schema.futureverse.com/path#> .
this:AccessoryEyewear a fvp:OnChainERC721Asset ;
.
`;
const accessoryEarsSchema = `
@prefix this: <http://schema.futureverse.dev/pb> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix fvp: <http://schema.futureverse.com/#> .
@prefix path: <http://schema.futureverse.com/path#> .
this:AccessoryEars a fvp:OnChainERC721Asset ;
.
`;
const SchemaCreation = () => {
const { createAsync: createSchemaAsync } = useCreateSchema();
const createPartybearSchema = async () => {
await createSchemaAsync({
name: "bear",
schema: bearSchema,
version: 0,
namespace,
});
};
const createAccessoryEyewearSchema = async () => {
await createSchemaAsync({
name: "accessoryEyewear",
schema: accessoryEyewearSchema,
version: 0,
namespace,
});
};
const createAccessoryEarsSchema = async () => {
await createSchemaAsync({
name: "AccessoryEars",
schema: accessoryEarsSchema,
version: 0,
namespace,
});
};
return (
<div>
<button onClick={createPartybearSchema}>Create Partybear Schema</button>
<button onClick={createAccessoryEyewearSchema}>Create AccessoryEyewear Schema</button>
<button onClick={createAccessoryEarsSchema}>Create AccessoryEars Schema</button>
</div>
);
};
Copy
Ask AI
mutation CreateSchema($input: CreateSchemaInput!) {
createSchema(input: $input) {
__typename
... on CreateSchemaSuccess {
schema {
id
name
version
namespace
schema
}
}
}
}
- Partybear schema”
Copy
Ask AI
{
"input": {
"name": "bear",
"schema": "@prefix this: <http://schema.futureverse.dev/pb>.\n@prefix sh: <http://www.w3.org/ns/shacl#>.\n@prefix fvp: <http://schema.futureverse.com/#>.\n@prefix path: <http://schema.futureverse.com/path#>.\n\nthis:Bear a fvp:OnChainERC721Asset;\n sh:property [\n sh:minCount 0;\n sh:maxCount 1;\n sh:class this:AccessoryEars;\n sh:path path:equippedWith_accessoryEars\n], [\n sh:minCount 0;\n sh:maxCount 1;\n sh:class this:AccessoryEyewear;\n sh:path path:equippedWith_accessoryEyewear\n].\n",
"version": 1,
"namespace": "http://schema.futureverse.dev/pb"
}
}
- AccessoryEyewear schema” fullWidth=“true”
Copy
Ask AI
{
"input": {
"name": "accessoryEyewear",
"schema": "@prefix this: <http://schema.futureverse.dev/pb> .\n@prefix sh: <http://www.w3.org/ns/shacl#> .\n@prefix fvp: <http://schema.futureverse.com/#> .\n@prefix path: <http://schema.futureverse.com/path#> .\n\nthis:AccessoryEyewear a fvp:OnChainERC721Asset ;\n .",
"version": 1,
"namespace": "http://schema.futureverse.dev/pb"
}
}
- AccessoryEars schema”
Copy
Ask AI
{
"input": {
"name": "AccessoryEars",
"schema": "@prefix this: <http://schema.futureverse.dev/pb> .\n@prefix sh: <http://www.w3.org/ns/shacl#> .\n@prefix fvp: <http://schema.futureverse.com/#> .\n@prefix path: <http://schema.futureverse.com/path#> .\n\nthis:AccessoryEars a fvp:OnChainERC721Asset ;\n .",
"version": 1,
"namespace": "http://schema.futureverse.dev/pb"
}
}
Asset Registration with Schema
https://ar-docs.futureverse.dev/collection/
Copy
Ask AI
const SchemaRegistration = () => {
const { createAsync } = useRegisterTokenSchema()
const register = async (collectionId, schemaId) => {
await createAsync({
collectionId,
schemaId,
})
}
return (
<div>
<button
onClick={() =>
register('7672:root:303204', 'http://schema.futureverse.dev/pb#bear')
}
>
Register party bear
</button>
<button
onClick={() =>
register(
'7672:root:240740',
'http://schema.futureverse.dev/pb#AccessoryEars',
)
}
>
Register AccessoryEars
</button>
<button
onClick={() =>
register(
'7672:root:245860',
'http://schema.futureverse.dev/pb#AccessoryEyewear',
)
}
>
Register AccessoryEyewear
</button>
</div>
)
}
Copy
Ask AI
const SchemaRegistration = () => {
const { createAsync } = useRegisterTokenSchema()
const register = async (collectionId, schemaId) => {
await createAsync({
collectionId,
schemaId,
})
}
return (
<div>
<button
onClick={() =>
register('7672:root:303204', 'http://schema.futureverse.dev/pb#bear')
}
>
Register party bear
</button>
<button
onClick={() =>
register(
'7672:root:240740',
'http://schema.futureverse.dev/pb#AccessoryEars',
)
}
>
Register AccessoryEars
</button>
<button
onClick={() =>
register(
'7672:root:245860',
'http://schema.futureverse.dev/pb#AccessoryEyewear',
)
}
>
Register AccessoryEyewear
</button>
</div>
)
}
Copy
Ask AI
mutation RegisterTokenSchema($input: RegisterTokenSchemaInput!) {
registerTokenSchema(input: $input) {
tokenSchema {
collectionId
id
schemaId
tokenId
version
}
}
}
1. Party bear input"
```json
{
"input": {
"collectionId": "7672:root:303204",
"schemaId": "http://schema.futureverse.dev/pb#bear"
}
}
- AccessoryEars input”
Copy
Ask AI
{
"input": {
"collectionId": "7672:root:240740",
"schemaId": "http://schema.futureverse.dev/pb#AccessoryEars"
}
}
- AccessoryEyewear”
Copy
Ask AI
{
"input": {
"collectionId": "7672:root:245860",
"schemaId": "http://schema.futureverse.dev/pb#AccessoryEyewear"
}
}
Find equitable slots for the party bear
https://ar-docs.futureverse.dev/manage-assets/QXNzZXQ6NzY3Mjpyb290OjMwMzIwNDoyMzI=
Copy
Ask AI
// An component to display all equitable slots for an party bear
const SwappablesRootAsset = ({ address, tokenId, collectionId}) => {
const { asset } = useGetAsset(
{
tokenId, // party bear token id
collectionId,
addresses: [address],
}
)
const { assets } = useAssets(
{
first: 1000,
addresses: [address],
}
)
type Slot = {
schemaName: string
assets: typeof assets
}
const [accessorySlots, setAccessorySlots] = useState<Slot[]>([])
useEffect(() => {
if (!assets || !asset) {
return
}
const updateSlots = async () => {
const slotSchemaNames = await getPaths(asset?.schema?.schema)
const schemaNamespace = currentAsset?.schema?.namespace
const slots = slotSchemaNames.map((schemaName) => {
const slotAssets = assets.filter(
(asset) =>
asset?.schema?.name.toLowerCase() === schemaName.toLowerCase() &&
asset.schema.namespace === schemaNamespace,
)
return {
assets: slotAssets,
schemaName,
}
})
setAccessorySlots(slots)
}
updateSlots()
}, [assets, asset])
return <div>display swappable slots for partybear</div>
}
Copy
Ask AI
// An component to display all equitable slots for an party bear
const SwappablesRootAsset = ({ address, tokenId, collectionId}) => {
const { asset } = useGetAsset(
{
tokenId, // party bear token id
collectionId,
addresses: [address],
}
)
const { assets } = useAssets(
{
first: 1000,
addresses: [address],
}
)
type Slot = {
schemaName: string
assets: typeof assets
}
const [accessorySlots, setAccessorySlots] = useState<Slot[]>([])
useEffect(() => {
if (!assets || !asset) {
return
}
const updateSlots = async () => {
const slotSchemaNames = await getPaths(asset?.schema?.schema)
const schemaNamespace = currentAsset?.schema?.namespace
const slots = slotSchemaNames.map((schemaName) => {
const slotAssets = assets.filter(
(asset) =>
asset?.schema?.name.toLowerCase() === schemaName.toLowerCase() &&
asset.schema.namespace === schemaNamespace,
)
return {
assets: slotAssets,
schemaName,
}
})
setAccessorySlots(slots)
}
updateSlots()
}, [assets, asset])
return <div>display swappable slots for partybear</div>
}
Equip and submit transaction
https://ar-docs.futureverse.dev/manage-assets/QXNzZXQ6NzY3Mjpyb290OjMwMzIwNDoyMzI=
Copy
Ask AI
// accessoryEarsAsset is one of the assets selected from last step's slot.assets
const EquipAccessory = (partybearAsset, accessoryEarsAsset) => {
const { submitAsync, transaction } = useSignAndSubmitTransaction()
const handleSave = async () => {
const { data: artm } = await getARTM()
artm.operations = []
artm.addOperation({
type: 'asset-link',
action: 'create',
args: [
`equippedWith_accessoryEars`,
partybearAsset.assetTree.nodeId,
accessoryEarsAsset.assetTree.nodeId,
],
})
submitAsync({ artm })
}
return <button onClick={submitAsync}>save</button>
}
Copy
Ask AI
// accessoryEarsAsset is one of the assets selected from last step's slot.assets
const EquipAccessory = (partybearAsset, accessoryEarsAsset) => {
const { submitAsync, transaction } = useSignAndSubmitTransaction()
const handleSave = async () => {
const { data: artm } = await getARTM()
artm.operations = []
artm.addOperation({
type: 'asset-link',
action: 'create',
args: [
`equippedWith_accessoryEars`,
partybearAsset.assetTree.nodeId,
accessoryEarsAsset.assetTree.nodeId,
],
})
submitAsync({ artm })
}
return <button onClick={submitAsync}>save</button>
}
Was this page helpful?
Assistant
Responses are generated using AI and may contain mistakes.