Skip to main content

Create Atom

Atoms are the fundamental building blocks in the Intuition system, representing discrete units of data that can be anything from a single concept to a complex entity. Each Atom is assigned a unique decentralized identifier (DID) and includes associated metadata, a wallet, and a vault.

Context

The createAtom and batchCreateAtom functions are part of the EthMultiVault contract, which manages the creation and management of Atoms and their associated vaults. When creating Atoms, the metadata is stored off-chain with only a URI reference stored on-chain. This design allows for maximum flexibility - developers can use any URI scheme and storage solution that best fits their needs.

For convenience, we provide a set of GraphQL mutations that help structure and publish Atom metadata following common schemas and best practices. These mutations will be continuously updated to support more schemas and improve interoperability. See our Off-Chain Metadata Guide for details on using these recommended patterns.

The following guide will focus solely on the on-chain aspects of creating an Atom using a URI.

createAtom

function createAtom(bytes calldata atomUri) external payable returns (uint256)

Parameters

  • atomUri : The URI point to the Atom’s metadata (typically stored off-chain)
  • value : Initial deposit into the Atom’s multivault. Must be ≥ to the atom creation cost.
  • Returns: uint256 - Created atom vault ID

Implementation

// useCreateAtom Hook
import { type GetContractReturnType } from 'viem'
import { base } from 'viem/chains'
import { useContractWriteAndWait } from './useContractWriteAndWait'
import { useMultivaultContract } from './useMultivaultContract'

export const useCreateAtom = () => {
const multivault = useMultivaultContract(
baseSepolia.id
) as GetContractReturnType

return useContractWriteAndWait({
...multivault,
functionName: 'createAtom',
})
}
// Usage Example
const {
writeAsync: writeCreateAtom,
awaitingWalletConfirmation,
awaitingOnChainConfirmation,
} = useCreateAtom()

async function handleCreateAtom(atomData: string) {
if (!awaitingOnChainConfirmation && !awaitingWalletConfirmation && writeCreateAtom) {
try {
const tx = await writeCreateAtom({
address: MULTIVAULT_CONTRACT_ADDRESS,
abi: multivaultAbi,
functionName: 'createAtom',
args: [toHex(atomData)],
value: atomCost, // Must be >= minimum creation cost
})

if (tx?.hash) {
const receipt = await publicClient.waitForTransactionReceipt({
hash: tx.hash,
})
// Handle success
}
} catch (error) {
// Handle error
}
}
}

createBatchAtom

function createAtomBatch(bytes[] calldata atomUris) external payable nonReentrant whenNotPaused returns (uint256[] memory)

Parameters

  • atomUris : The URIs point to the Atoms’ metadata (typically stored off-chain)
  • value : Initial deposit into the Atom’s multivault. Must be ≥ to the atom creation cost * length of atomUris. This will get distributed evenly across all created atoms.
  • Returns uint256[] - Created atoms’ vault ID(s)

Implementation

// useBatchCreateAtom Hook
import { type GetContractReturnType } from 'viem'
import { base } from 'viem/chains'
import { useContractWriteAndWait } from './useContractWriteAndWait'
import { useMultivaultContract } from './useMultivaultContract'

export const useBatchCreateAtom = () => {
const multivault = useMultivaultContract(
base.id
) as GetContractReturnType

return useContractWriteAndWait({
...multivault,
functionName: 'createAtomBatch',
})
}
// Usage Example
const {
writeAsync: writeBatchCreateAtom,
awaitingWalletConfirmation,
awaitingOnChainConfirmation,
} = useBatchCreateAtom()

async function handleBatchCreateAtom(atomUris: string[]) {
const value = BigInt(atomCost) * BigInt(atomUris.length)

if (!awaitingOnChainConfirmation && !awaitingWalletConfirmation && writeBatchCreateAtom) {
try {
const tx = await writeBatchCreateAtom({
address: MULTIVAULT_CONTRACT_ADDRESS,
abi: multivaultAbi,
functionName: 'createAtomBatch',
args: [atomUris.map(data => toHex(data))],
value: value, // Must be >= minimum creation cost * number of atoms
})

if (tx?.hash) {
const receipt = await publicClient.waitForTransactionReceipt({
hash: tx.hash,
})
// Handle success
}
} catch (error) {
// Handle error
}
}
}

Cost Considerations

  1. Creation Cost:
    • Minimum ETH required to create an Atom
    • Retrieved via getAtomCost()
    • Includes protocol fee sent to treasury
    • Must be included in transaction's value parameter
  2. Initial Deposit:
    • Any ETH sent above the creation cost
    • Becomes initial stake in the Atom's vault
    • Subject to entry fees
    • Grants fractional ownership in the vault

See also: