Authentication
- Getting Started
- React
- API Reference
Transactions
- Overview
- Getting Started
- Usage
- Helper Functions
Assets
- Overview
- Getting Started
- Collectibles/NFTs
- Asset Register Transaction Message (ARTM)
- Swappables
- Tokens
- Asset Tree
- Error messages
Swappables
Owner Link
Overview
If you own both the parent and child collections and want to link assets between them, you can use the owner-link
operation type as shown below.
Asset link creation operation
An asset link creation operation within an ARTM typically consists of the following structure:
Copy
Ask AI
{
type: 'owner-link',
action: 'create',
args: [
// Operator
'equipWith_asmBrain',
// Opearand A: Boxer Asset ID
'did:fv-asset:1:evm:0x6bca6de2dbdc4e0d41f7273011785ea16ba47182:1000',
// Opearand B: Brain Asset ID
'did:fv-asset:1:evm:0x1ea66a857de297471bc12dd12d93853ff6617284:21',
],
}
Ownership check for link creation
To create links, the sender of the transaction must be the owner of both assets’ collections. Linking between assets owned on a Pass account and the Pass account owner’s EOA is allowed. Links can also be created across chains as long as the ownership resolution is satisfied.
Usage
Create Link
Copy
Ask AI
import {
useGetARTM,
useSignAndSubmitTransaction,
useGetTransaction,
} from '@futureverse/asset-register-react/v2'
const linkOperation = {
type: 'owner-link',
action: 'create',
args: [
'equipWith_asmBrain',
// Boxer
'did:fv-asset:1:evm:0x6bca6de2dbdc4e0d41f7273011785ea16ba47182:1000',
// Brain
'did:fv-asset:1:evm:0x1ea66a857de297471bc12dd12d93853ff6617284:21',
],
}
const LinkAccessory = ({ address }) => {
const {
artm,
reactQuery: { refetch: getARTM },
} = useGetARTM(
{
address,
[],
},
{ enabled: false },
)
const { submitAsync, transaction } = useSignAndSubmitTransaction()
// Polling tx status after submitted
const { transaction: transactionStatus } = useGetTransaction(
{ transactionHash: transaction?.transactionHash as any },
{
refetchInterval: (data) => (data?.status === 'PENDING' ? 2000 : false),
enabled: !!transaction?.transactionHash,
},
)
const submitARTM = async () => {
const { data: artm } = await getARTM()
if (!artm) {
return
}
artm.addOperation(linkOperation)
return submitAsync({ artm })
}
return (
<>
<button onClick={submitARTM}>Submit link accessory TX</button>
{transactionStatus && <div>{`tx status: ${transactionStatus.status}`}</div>}
</>
)
}
Copy
Ask AI
import {
useGetARTM,
useSignAndSubmitTransaction,
useGetTransaction,
} from '@futureverse/asset-register-react/v2'
const linkOperation = {
type: 'owner-link',
action: 'create',
args: [
'equipWith_asmBrain',
// Boxer
'did:fv-asset:1:evm:0x6bca6de2dbdc4e0d41f7273011785ea16ba47182:1000',
// Brain
'did:fv-asset:1:evm:0x1ea66a857de297471bc12dd12d93853ff6617284:21',
],
}
const LinkAccessory = ({ address }) => {
const {
artm,
reactQuery: { refetch: getARTM },
} = useGetARTM(
{
address,
[],
},
{ enabled: false },
)
const { submitAsync, transaction } = useSignAndSubmitTransaction()
// Polling tx status after submitted
const { transaction: transactionStatus } = useGetTransaction(
{ transactionHash: transaction?.transactionHash as any },
{
refetchInterval: (data) => (data?.status === 'PENDING' ? 2000 : false),
enabled: !!transaction?.transactionHash,
},
)
const submitARTM = async () => {
const { data: artm } = await getARTM()
if (!artm) {
return
}
artm.addOperation(linkOperation)
return submitAsync({ artm })
}
return (
<>
<button onClick={submitARTM}>Submit link accessory TX</button>
{transactionStatus && <div>{`tx status: ${transactionStatus.status}`}</div>}
</>
)
}
Copy
Ask AI
import { AssetRegister } from '@futureverse/asset-register'
import {
AssetTransactionMessage,
Signature,
chainAddressFromString,
} from '@futureverse/asset-register/types'
import { ARTM, STATEMENTS } from '@futureverse/artm'
const address = "YOUR_WALLET_ADDRESS"
const linkOperation = {
type: 'owner-link',
action: 'create',
args: [
'equipWith_asmBrain',
'did:fv-asset:1:evm:0x6bca6de2dbdc4e0d41f7273011785ea16ba47182:1000',
'did:fv-asset:1:evm:0x1ea66a857de297471bc12dd12d93853ff6617284:21',
],
}
const ar = new AssetRegister({
...
})
const getARTM = async () => {
const nonce = await ar.nonceForChainAddress(chainAddressFromString(address))
return new ARTM({
operations: [linkOperation],
nonce,
address,
statement: STATEMENTS.ASSET_UPDATE,
})
}
const signAndSubmit = async () => {
const artm = await getARTM()
await ar.sign(artm)
const assetInput = {
transaction: artm.message as AssetTransactionMessage,
signature: artm.signature as Signature,
}
return ar.submitTransaction(assetInput)
}
signAndSubmit()
-
Get nonce.
CopyAsk AIquery GetNonceForChainAddress($input: NonceInput!) { getNonceForChainAddress(input: $input) }
CopyAsk AI{ "input": { "chainAddress": "0x2d2438c6281b5115733287fc279f854c868d3ee2" } }
-
Get message and signature through ARTM.
CopyAsk AIimport { ARTM, STATEMENTS } from '@futureverse/artm' const linkOperation = { type: 'owner-link', action: 'create', args: [ 'equipWith_asmBrain', 'did:fv-asset:1:evm:0x6bca6de2dbdc4e0d41f7273011785ea16ba47182:1000', 'did:fv-asset:1:evm:0x1ea66a857de297471bc12dd12d93853ff6617284:21', ], } const artm = new ARTM({ operations: [linkOperation], nonce, address, statement: STATEMENTS.ASSET_UPDATE, })
-
Submit transaction
CopyAsk AImutation SubmitTransaction($input: SubmitTransactionInput!) { submitTransaction(input: $input) { transactionHash } }
CopyAsk AI{ "input": { "transaction": artm.message, "signature": artm.signature } }
-
Check transaction status
CopyAsk AIquery GetTransaction($transactionHash: TransactionHash!) { transaction(transactionHash: $transactionHash) { id status transactionHash error { message code } } }
CopyAsk AI{ "transactionHash": "0x0f35cc253abccfb69ecfba5a3fc6696a518aa5ad8bc1e19c71c73446269057c8" }
Delete Link
Copy
Ask AI
import {
useGetARTM,
useSignAndSubmitTransaction,
useGetTransaction,
} from '@futureverse/asset-register-react/v2'
const linkOperation = {
type: 'owner-link',
action: 'delete',
args: [
'equipWith_asmBrain',
// Boxer
'did:fv-asset:1:evm:0x6bca6de2dbdc4e0d41f7273011785ea16ba47182:1000',
// Brain
'did:fv-asset:1:evm:0x1ea66a857de297471bc12dd12d93853ff6617284:21',
],
}
const LinkAccessory = ({ address }) => {
const {
artm,
reactQuery: { refetch: getARTM },
} = useGetARTM(
{
address,
[],
},
{ enabled: false },
)
const { submitAsync, transaction } = useSignAndSubmitTransaction()
// Polling tx status after submitted
const { transaction: transactionStatus } = useGetTransaction(
{ transactionHash: transaction?.transactionHash as any },
{
refetchInterval: (data) => (data?.status === 'PENDING' ? 2000 : false),
enabled: !!transaction?.transactionHash,
},
)
const submitARTM = async () => {
const { data: artm } = await getARTM()
if (!artm) {
return
}
artm.addOperation(linkOperation)
return submitAsync({ artm })
}
return (
<>
<button onClick={submitARTM}>Submit link accessory TX</button>
{transactionStatus && <div>{`tx status: ${transactionStatus.status}`}</div>}
</>
)
}
Copy
Ask AI
import {
useGetARTM,
useSignAndSubmitTransaction,
useGetTransaction,
} from '@futureverse/asset-register-react/v2'
const linkOperation = {
type: 'owner-link',
action: 'delete',
args: [
'equipWith_asmBrain',
// Boxer
'did:fv-asset:1:evm:0x6bca6de2dbdc4e0d41f7273011785ea16ba47182:1000',
// Brain
'did:fv-asset:1:evm:0x1ea66a857de297471bc12dd12d93853ff6617284:21',
],
}
const LinkAccessory = ({ address }) => {
const {
artm,
reactQuery: { refetch: getARTM },
} = useGetARTM(
{
address,
[],
},
{ enabled: false },
)
const { submitAsync, transaction } = useSignAndSubmitTransaction()
// Polling tx status after submitted
const { transaction: transactionStatus } = useGetTransaction(
{ transactionHash: transaction?.transactionHash as any },
{
refetchInterval: (data) => (data?.status === 'PENDING' ? 2000 : false),
enabled: !!transaction?.transactionHash,
},
)
const submitARTM = async () => {
const { data: artm } = await getARTM()
if (!artm) {
return
}
artm.addOperation(linkOperation)
return submitAsync({ artm })
}
return (
<>
<button onClick={submitARTM}>Submit link accessory TX</button>
{transactionStatus && <div>{`tx status: ${transactionStatus.status}`}</div>}
</>
)
}
Copy
Ask AI
import { AssetRegister } from '@futureverse/asset-register'
import {
AssetTransactionMessage,
Signature,
chainAddressFromString,
} from '@futureverse/asset-register/types'
import { ARTM, STATEMENTS } from '@futureverse/artm'
const address = "YOUR_WALLET_ADDRESS"
const linkOperation = {
type: 'owner-link',
action: 'delete',
args: [
'equipWith_asmBrain',
'did:fv-asset:1:evm:0x6bca6de2dbdc4e0d41f7273011785ea16ba47182:1000',
'did:fv-asset:1:evm:0x1ea66a857de297471bc12dd12d93853ff6617284:21',
],
}
const ar = new AssetRegister({
...
})
const getARTM = async () => {
const nonce = await ar.nonceForChainAddress(chainAddressFromString(address))
return new ARTM({
operations: [linkOperation],
nonce,
address,
statement: STATEMENTS.ASSET_UPDATE,
})
}
const signAndSubmit = async () => {
const artm = await getARTM()
await ar.sign(artm)
const assetInput = {
transaction: artm.message as AssetTransactionMessage,
signature: artm.signature as Signature,
}
return ar.submitTransaction(assetInput)
}
signAndSubmit()
-
Get nonce.
CopyAsk AIquery GetNonceForChainAddress($input: NonceInput!) { getNonceForChainAddress(input: $input) }
CopyAsk AI{ "input": { "chainAddress": "0x2d2438c6281b5115733287fc279f854c868d3ee2" } }
-
Get message and signature through ARTM.
CopyAsk AIimport { ARTM, STATEMENTS } from '@futureverse/artm' const linkOperation = { type: 'owner-link', action: 'delete', args: [ 'equipWith_asmBrain', 'did:fv-asset:1:evm:0x6bca6de2dbdc4e0d41f7273011785ea16ba47182:1000', 'did:fv-asset:1:evm:0x1ea66a857de297471bc12dd12d93853ff6617284:21', ], } const artm = new ARTM({ operations: [linkOperation], nonce, address, statement: STATEMENTS.ASSET_UPDATE, })
-
Submit transaction
CopyAsk AImutation SubmitTransaction($input: SubmitTransactionInput!) { submitTransaction(input: $input) { transactionHash } }
CopyAsk AI{ "input": { "transaction": artm.message, "signature": artm.signature } }
-
Check transaction status
CopyAsk AIquery GetTransaction($transactionHash: TransactionHash!) { transaction(transactionHash: $transactionHash) { id status transactionHash error { message code } } }
CopyAsk AI{ "transactionHash": "0x0f35cc253abccfb69ecfba5a3fc6696a518aa5ad8bc1e19c71c73446269057c8" }
Was this page helpful?
Assistant
Responses are generated using AI and may contain mistakes.