Building with VIPs (Vexidus Intent Programs)
This guide shows how to build, register, and invoke VIPs on Vexidus. VIPs replace smart contracts with declarative composition templates -- no compilation, no bytecode, no VM.
Quick Start
1. Write Your VIP
A VIP is a JSON document that describes what operations to execute and what parameters to accept:
{
"namespace": "myapp",
"name": "reward_and_stake",
"version": 1,
"author": "Vx0YourAddressHere",
"description": "Mint reward tokens and auto-stake them",
"params": [
{
"name": "reward_collection",
"type": "Address",
"required": true,
"description": "Multi-token collection for rewards"
},
{
"name": "amount",
"type": "Amount",
"required": true,
"description": "Amount to mint and stake"
},
{
"name": "pool",
"type": "Address",
"required": true,
"description": "Staking pool address"
}
],
"steps": [
{
"id": "mint",
"operation": "MintMultiToken",
"args": [
["collection", "${params.reward_collection}"],
["type_id", "0"],
["to", "${sender}"],
["amount", "${params.amount}"]
]
},
{
"id": "stake",
"operation": "StakeToPool",
"args": [
["pool", "${params.pool}"],
["amount", "${params.amount}"]
]
}
],
"returns": [
["mint_result", "${steps.mint.result.tx_hash}"],
["stake_result", "${steps.stake.result.tx_hash}"]
]
}
2. Simulate Before Registering
Use the CLI or RPC to dry-run your VIP:
vexidus vip simulate myapp reward_and_stake \
--params '[["reward_collection","Vx0..."],["amount","1000000000"],["pool","Vx0..."]]'
This shows you the expanded operations, estimated gas, and safety analysis -- without spending anything.
3. Register
vexidus vip register \
--program '{"namespace":"myapp","name":"reward_and_stake",...}' \
--from Vx0YourAddress
The chain runs static safety analysis. If it passes, your VIP is live. If it fails, you get detailed error messages explaining which rule was violated.
4. Users Invoke Your VIP
Via RPC:
{
"method": "vex_submitIntent",
"params": [
"run myapp/reward_and_stake with reward_collection=Vx0... amount=1000000000 pool=Vx0...",
"Vx0UserAddress"
]
}
Via CLI:
vexidus intent "run myapp/reward_and_stake with amount=1000000000"
Parameter Types
| Type | JSON Value | Example |
|---|---|---|
String | "hello" | Names, descriptions, labels |
Address | "Vx0..." | Vexidus addresses |
Amount | "1000000000" | Raw amounts (scaled by token decimals) |
U8 | 8 | Small integers (0-255) |
U64 | 12345 | Large integers |
Bool | true | Flags |
AddressArray | ["Vx0...","Vx0..."] | Lists of addresses (max 20) |
U64Array | [0, 1, 6, 7] | Lists of integers (max 50) |
StringArray | ["a","b"] | Lists of strings (max 20) |
Allowed Operations
These operations can be used in VIP steps:
Token Operations: Transfer, CreateToken, CreateNftCollection, MintNft, TransferNft, BurnNft, CreateMultiTokenCollection, DefineTokenType, MintMultiToken, BatchMintMultiToken, TransferMultiToken, BatchTransferMultiToken, BurnMultiToken, UpdateTokenMetadata, LockTokenMetadata
DeFi: CreatePool, AddLiquidity, Swap
Governance: CreateMultiSig, ProposeMultiSigTx, CreateProposal, CreateDAO
Staking: Stake, Delegate, CreateStakingPool, StakeToPool
Other: RegisterName, Anchor
Operations NOT Allowed in VIPs
Bridge operations (BridgeDeposit, BridgeWithdraw), key management (RemoveKey, RotateKey), upgrade operations (ScheduleUpgrade), stablecoin admin (StablePause, StableBlacklist), and Deploy/ContractCall are excluded for safety. These require direct user signatures.
Loops
VIPs support iterating over array parameters:
{
"id": "create_types",
"operation": "DefineTokenType",
"args": [
["collection", "${steps.collection.result.address}"],
["type_id", "${item}"],
["name", "Type ${item}"]
],
"loop_over": "params.checkpoint_types"
}
If the user passes checkpoint_types: [0, 1, 6, 7], this step executes 4 times, once for each value.
Limit: Arrays can have at most 50 elements. Total expanded operations across all steps cannot exceed 50.
Step References
Steps can reference results from prior steps:
{
"id": "collection",
"operation": "CreateNftCollection",
"args": [["name", "My Collection"]]
},
{
"id": "mint",
"operation": "MintNft",
"args": [
["collection", "${steps.collection.result.address}"],
["recipient", "${sender}"]
]
}
Rules:
- Steps can only reference steps that come BEFORE them
- Forward references are rejected at registration
- Self-references are rejected
Safety Rules
Your VIP must pass these rules to be registered:
- No hardcoded recipient addresses in Transfer, MintNft, MintMultiToken, etc. Use
${sender}or${params.*}. - No hidden approvals -- Approve spender must be
${params.*}(user explicitly provides it). - All operations must be in the allowed list -- no bridge admin, no key management.
- Max 50 expanded operations -- loops count against this.
- Max 5M estimated gas -- complex programs get a warning.
- Valid template expressions -- all
${params.X}must reference declared parameters. - Safe URIs -- no XSS, no
javascript:, nodata:schemes. - Unique step IDs -- no duplicates, no empty IDs.
- Valid namespace -- 3-32 chars, starts with a letter, alphanumeric + hyphens.
Data Anchoring
The Anchor operation lets you write a BLAKE3 hash to the chain without token semantics:
# Anchor a document hash
vexidus vip anchor \
--namespace myapp \
--key $(echo -n "invoice-2026-001" | xxd -p) \
--hash VxhABC123... \
--metadata-uri "ipfs://QmDocHash" \
--from Vx0YourAddress
# Verify later
vexidus vip verify myapp $(echo -n "invoice-2026-001" | xxd -p) VxhABC123...
Gas cost: 5,000 (10x cheaper than token mints). Use this for document attestation, data integrity proofs, supply chain checkpoints, or any scenario where you need to prove "this data existed at this time."
Example: Supply Chain Shipment VIP
{
"namespace": "logistics",
"name": "create_tracked_shipment",
"description": "Creates a shipment with NFT identity, checkpoint collection, and custody multi-sig",
"params": [
{ "name": "contents", "type": "String", "required": true, "description": "Cargo description" },
{ "name": "parties", "type": "AddressArray", "required": true, "description": "Custody chain participants" },
{ "name": "threshold", "type": "U8", "required": true, "description": "Multi-sig approval threshold" },
{ "name": "checkpoint_types", "type": "U64Array", "required": false, "default_value": "0,1,6,7", "description": "Checkpoint type IDs" }
],
"steps": [
{
"id": "shipment_collection",
"operation": "CreateNftCollection",
"args": [
["name", "Ship-${params.contents}"],
["symbol", "SHIP"],
["base_uri", ""],
["max_supply", "1"],
["royalty_bps", "0"],
["description", "Tracked shipment"],
["owner", "${sender}"]
]
},
{
"id": "checkpoint_collection",
"operation": "CreateMultiTokenCollection",
"args": [
["name", "Checkpoints-${params.contents}"],
["symbol", "CKP"],
["base_uri", ""],
["royalty_bps", "0"],
["description", "Shipment checkpoints"],
["owner", "${sender}"]
]
},
{
"id": "define_types",
"operation": "DefineTokenType",
"args": [
["collection", "${steps.checkpoint_collection.result.address}"],
["type_id", "${item}"],
["name", "Checkpoint-${item}"],
["metadata_uri", ""],
["is_fungible", "true"]
],
"loop_over": "params.checkpoint_types"
},
{
"id": "custody",
"operation": "CreateMultiSig",
"args": [
["signers", "${params.parties}"],
["threshold", "${params.threshold}"],
["label", "Custody-${params.contents}"]
]
}
],
"returns": [
["shipment_collection", "${steps.shipment_collection.result.address}"],
["checkpoint_collection", "${steps.checkpoint_collection.result.address}"],
["custody_multisig", "${steps.custody.result.address}"]
]
}
One VIP invocation creates everything a logistics company needs to track a shipment: NFT identity, checkpoint event system, and multi-party custody chain. No smart contract. No compilation. No bytecode verification.
Namespace Ownership
- The first address to register a VIP in a namespace owns that namespace
- Only the owner can register new programs in their namespace
- Namespaces
vexidus,vex,foundation,system,coreare reserved for governance - Namespaces must be 3-32 characters, alphanumeric with hyphens, starting with a letter
Versioning
VIPs are versioned automatically. Each registration of the same namespace/name increments the version. Users can invoke a specific version or default to latest:
# Invoke latest version
vexidus intent "run myapp/my_program with ..."
# Invoke specific version
vexidus intent "run myapp/my_program v2 with ..."
Intent Studio (VexForge)
VIPs can be registered, browsed, simulated, and invoked through Intent Studio on VexForge -- a web UI for building and managing VIPs without using the CLI.