Models

Models are AI inference services registered on-chain. Each model defines its execution parameters, fees, and mining eligibility.

The Model Data Structure

The Model struct contains all on-chain data about a registered model, including its fees, template information, mining rate, and access controls.

Properties

  • Name
    fee
    Type
    uint256
    Description

    Flat fee imposed on each task using this model.

  • Name
    addr
    Type
    address
    Description

    Address the model receives fees to.

  • Name
    rate
    Type
    uint256
    Description

    Multiplier for reward generation. 0 means not mineable. 1e18 means 1x.

  • Name
    cid
    Type
    string
    Description

    CID containing template schema.


READEngine

Retrieve model

Look up a model based on its ID.

Request

CALL
Engine
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/EngineV1.sol/EngineV1.json';

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);

const engine = new ethers.Contract(
  Config.engineAddress,
  EngineArtifact.abi,
  provider,
)

const modelid = 'model id to look up';
const model = await engine.models(modelid);
const { fee, addr, rate, cid } = model;

Model Allow Lists (V6+)

What are Model Allow Lists?

Model allow lists enable creators to control which validators can submit solutions. This provides:

  • Quality assurance during model launch phases
  • Private deployments for enterprise models
  • Gradual rollouts from trusted miners to permissionless
  • Controlled solver network for model token launches

Key Points

  • Allow lists are optional - models work permissionlessly by default
  • Only model owner or contract owner can manage the allow list
  • Once disabled with disableModelAllowList(), cannot be re-enabled (security feature)
  • Validators can check permissions with isSolverAllowed() and modelRequiresAllowList()

WRITEEngine

Register model

Register a new model with Arbius. This allows other validators know it is available, and makes it available for task creators to specify. You can provide a smart contract address as the parameter for addr to build tokenized models, or just have fees go to a regular address. Fee can be 0 if you would like it to be free to use. All fees are in Arbius tokens.

Ensure your cid parameter points to a valid schema.

It is highly recommended to read the guide Adding Models before attempting to register a model.

Request

WRITE
Engine
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/EngineV1.sol/EngineV1.json';

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);

const wallet = new ethers.Wallet(
  process.env.PRIVATE_KEY,
  provider,
);

const engine = new ethers.Contract(
  Config.engineAddress,
  EngineArtifact.abi,
  wallet,
)

const params = {
  addr: wallet.address,
  fee: ethers.utils.parseEther('0.1'),
  template: {},
}

const tx = await engine.registerModel(
  params.addr,
  params.fee,
  ethers.utils.hexlify(ethers.utils.toUtf8Bytes(params.template)),
)
const receipt = await tx.wait();

WRITEEngine

Register model with allow list (V6+)

This function registers a model and immediately sets up an allow list of approved solvers. Only addresses in the allow list will be able to submit solutions for this model.

Use cases:

  • Quality assurance during model launch
  • Private enterprise models
  • Gradual rollouts from trusted miners to permissionless
  • Model token launches requiring controlled solver network

Request

WRITE
Engine
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/V2_EngineV6.sol/V2_EngineV6.json';

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);

const wallet = new ethers.Wallet(
  process.env.PRIVATE_KEY,
  provider,
);

const engine = new ethers.Contract(
  Config.engineAddress,
  EngineArtifact.abi,
  wallet,
)

const params = {
  addr: wallet.address,
  fee: ethers.utils.parseEther('0.1'),
  template: {},
  allowList: [
    '0x1111111111111111111111111111111111111111',
    '0x2222222222222222222222222222222222222222',
  ]
}

const tx = await engine.registerModelWithAllowList(
  params.addr,
  params.fee,
  ethers.utils.hexlify(ethers.utils.toUtf8Bytes(params.template)),
  params.allowList,
)
const receipt = await tx.wait();

READEngine

Check solver permissions (V6+)

Check if a solver is allowed to submit solutions for a model. Returns true if the model doesn't have an allow list, or if the solver is on the allow list.

Request

READ
Engine
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/V2_EngineV6.sol/V2_EngineV6.json';

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);

const engine = new ethers.Contract(
  Config.engineAddress,
  EngineArtifact.abi,
  provider,
)

const modelid = '0x...'
const solver = '0x...'

const isAllowed = await engine.isSolverAllowed(modelid, solver);
const requiresAllowList = await engine.modelRequiresAllowList(modelid);

WRITEEngine (Model Owner)

Manage model allow list (V6+)

Model owners can add or remove solvers from their model's allow list. Only works if the model has an active allow list.

Important: Once disabled with disableModelAllowList(), the allow list cannot be re-enabled for security reasons.

Request

WRITE
Engine
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/V2_EngineV6.sol/V2_EngineV6.json';

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);

const wallet = new ethers.Wallet(
  process.env.PRIVATE_KEY,
  provider,
);

const engine = new ethers.Contract(
  Config.engineAddress,
  EngineArtifact.abi,
  wallet,
)

const modelid = '0x...'

// Add solvers to allow list
const solversToAdd = ['0x...', '0x...']
let tx = await engine.addToModelAllowList(modelid, solversToAdd)
await tx.wait()

// Remove solvers from allow list
const solversToRemove = ['0x...']
tx = await engine.removeFromModelAllowList(modelid, solversToRemove)
await tx.wait()

// Disable allow list (irreversible!)
tx = await engine.disableModelAllowList(modelid)
await tx.wait()