Skip to main content

Overview

The intent system enables programmable cross-chain operations and conditional execution. Users can create intents that solvers fulfill in exchange for rewards.

Intent Types

IntentType

Enum defining supported intent types. Location: src/intents.rs:44
pub enum IntentType {
    AnchorBitcoinFill = 1,
    RiscVProgram = 2,
}
AnchorBitcoinFill
1
Intent for Bitcoin L1 fills - requires on-chain verification
RiscVProgram
2
Intent for RISC-V program execution via Cartesi

Core Structures

Intent

Represents an intent with associated value and state. Location: src/intents.rs:412
pub struct Intent {
    pub data: Bytes,
    pub value: u64,
    pub status: IntentStatus,
    pub last_command: IntentCommandType,
    pub creator: Address,
}
data
Bytes
CBOR-encoded IntentData containing type and payload
value
u64
Value locked in the intent (in wei). Currently limited to u64::MAX (~18.4 ETH).
status
IntentStatus
Current status: Submitted, Locked, Solved, or Cancelled
last_command
IntentCommandType
Last operation performed on the intent
creator
Address
Address that created the intent

IntentStatus

Intent lifecycle states. Location: src/intents.rs:391
pub enum IntentStatus {
    Submitted,
    Locked(Address),
    Solved,
    Cancelled,
}
Submitted
variant
Intent created and awaiting a solver
Locked
Locked(Address)
Intent locked by a solver (contains solver’s address)
Solved
variant
Intent successfully fulfilled
Cancelled
variant
Intent cancelled by creator

IntentCommandType

Commands that can be performed on intents. Location: src/intents.rs:403
pub enum IntentCommandType {
    Created = 1,
    CancelIntent = 2,
    LockIntentForSolving = 3,
    SolveIntent = 4,
    CancelIntentLock = 5,
}

IntentData

CBOR-encoded intent data structure. Location: src/intents.rs:58
pub struct IntentData {
    pub intent_type: IntentType,
    pub data: Vec<u8>,
}

Methods

from_cbor
fn(cbor_bytes: &[u8]) -> Result<Self>
Deserializes IntentData from CBOR bytes.
to_cbor
fn(&self) -> Result<Vec<u8>>
Serializes IntentData to CBOR bytes.
parse_anchor_bitcoin_fill
fn(&self) -> Result<AnchorBitcoinFill>
Parses the data field as AnchorBitcoinFill. Returns error if intent type doesn’t match.
parse_riscv_program
fn(&self) -> Result<RiscVProgramIntent>
Parses the data field as RiscVProgramIntent. Returns error if intent type doesn’t match.

Bitcoin Fill Intent

AnchorBitcoinFill

Intent for Bitcoin L1 fills. Location: src/intents.rs:87
pub struct AnchorBitcoinFill {
    pub bitcoin_address: Vec<u8>,
    pub amount: U256,
    pub max_fee: U256,
    pub expire_by: u64,
}
bitcoin_address
Vec<u8>
Bitcoin address as UTF-8 bytes
amount
U256
Amount in satoshis to receive on Bitcoin
max_fee
U256
Maximum fee in satoshis the user is willing to pay
expire_by
u64
Expiration timestamp for the intent

Methods

from_bitcoin_address
fn
pub fn from_bitcoin_address(
    bitcoin_address: &str,
    amount: U256,
    max_fee: U256,
    expire_by: u64,
) -> Result<Self>
Creates an AnchorBitcoinFill from a Bitcoin address string.
to_cbor
fn(&self) -> Result<Vec<u8>>
Serializes to CBOR bytes.
from_cbor
fn(cbor_bytes: &[u8]) -> Result<Self>
Deserializes from CBOR bytes.
parse_bitcoin_address
fn(&self) -> Result<String>
Parses and validates the Bitcoin address, returning it as a string.

create_anchor_bitcoin_fill_intent

Helper function to create a Bitcoin fill intent. Location: src/intents.rs:163
pub fn create_anchor_bitcoin_fill_intent(
    bitcoin_address: &str,
    amount: U256,
    max_fee: U256,
    expire_by: u64,
) -> Result<IntentData>
bitcoin_address
&str
Bitcoin address to receive funds
amount
U256
Amount in satoshis
max_fee
U256
Maximum acceptable fee
expire_by
u64
Expiration timestamp
Returns: IntentData ready to be submitted

Example

use core_lane::{create_anchor_bitcoin_fill_intent, U256};

let intent_data = create_anchor_bitcoin_fill_intent(
    "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
    U256::from(100000), // 100k satoshis
    U256::from(1000),   // max 1k sat fee
    1735689600,         // expiry timestamp
)?;

let intent_cbor = intent_data.to_cbor()?;

RISC-V Program Intent

RiscVProgramIntent

Intent for executing RISC-V programs. Location: src/intents.rs:95
pub struct RiscVProgramIntent {
    pub blob_hash: [u8; 32],
    pub extra_data: Vec<u8>,
}
blob_hash
[u8; 32]
Hash of the stored blob containing the RISC-V program
extra_data
Vec<u8>
Additional data passed to the program

Intent Operations

IntentCall

Enum representing decoded intent system calls. Location: src/intents.rs:195
pub enum IntentCall {
    StoreBlob { data: Vec<u8>, expiry_time: U256 },
    Intent { intent_data: Vec<u8>, nonce: U256 },
    IntentFromBlob { blob_hash: B256, nonce: U256, extra_data: Vec<u8> },
    LockIntentForSolving { intent_id: B256, data: Vec<u8> },
    SolveIntent { intent_id: B256, data: Vec<u8> },
    CancelIntent { intent_id: B256, data: Vec<u8> },
    CancelIntentLock { intent_id: B256, data: Vec<u8> },
    IsIntentSolved { intent_id: B256 },
    CreateIntentAndLock { eip712sig: Vec<u8>, lock_data: Vec<u8> },
    // ... other variants
}

decode_intent_calldata

Decodes transaction calldata into an IntentCall. Location: src/intents.rs:257
pub fn decode_intent_calldata(calldata: &[u8]) -> Option<IntentCall>
calldata
&[u8]
Transaction calldata bytes
Returns: Decoded IntentCall or None if not a valid intent call

Example: Decoding Intent Calldata

use core_lane::{decode_intent_calldata, IntentCall};

let calldata = tx.input();
if let Some(intent_call) = decode_intent_calldata(&calldata) {
    match intent_call {
        IntentCall::Intent { intent_data, nonce } => {
            println!("Creating intent with nonce {}", nonce);
        }
        IntentCall::SolveIntent { intent_id, data } => {
            println!("Solving intent {}", intent_id);
        }
        _ => {}
    }
}

Intent Lifecycle

1. Create Intent

Send a transaction to CoreLaneAddresses::exit_marketplace() with:
  • Function: intent(bytes intentData, uint256 nonce)
  • Value: Amount to lock in the intent
Intent ID is calculated as:
keccak256(sender || nonce || intent_data)

2. Lock Intent for Solving

Solvers lock an intent to claim the right to solve it:
  • Function: lockIntentForSolving(bytes32 intentId, bytes data)
  • Changes status from Submitted to Locked(solver_address)

3. Solve Intent

Solver provides proof of fulfillment:
  • Function: solveIntent(bytes32 intentId, bytes data)
  • For AnchorBitcoinFill: Requires Bitcoin L1 verification
  • For RiscVProgram: Executes the program and validates output
  • Transfers locked value to solver

4. Cancel Intent

Creator can cancel and recover funds:
  • Function: cancelIntent(bytes32 intentId, bytes data)
  • Only creator can cancel
  • Cannot cancel if already solved

5. Cancel Lock

Solver can release their lock:
  • Function: cancelIntentLock(bytes32 intentId, bytes data)
  • Only current locker can cancel
  • Returns intent to Submitted status

Intent System Interface

Solidity interface for the intent system:
interface IntentSystem {
    function storeBlob(bytes data, uint256 expiryTime) payable;
    function intent(bytes intentData, uint256 nonce) payable returns (bytes32 intentId);
    function intentFromBlob(bytes32 blobHash, uint256 nonce, bytes extraData) payable returns (bytes32);
    function cancelIntent(bytes32 intentId, bytes data) payable;
    function lockIntentForSolving(bytes32 intentId, bytes data) payable;
    function solveIntent(bytes32 intentId, bytes data) payable;
    function cancelIntentLock(bytes32 intentId, bytes data) payable;
    function isIntentSolved(bytes32 intentId) view returns (bool);
    function createIntentAndLock(bytes eip712sig, bytes lockData) returns (bytes32 intentId);
}

Complete Example

use core_lane::{
    create_anchor_bitcoin_fill_intent,
    IntentData, IntentStatus, IntentType,
    StateManager, BundleStateManager,
    U256, B256, Address,
};

// Create a Bitcoin fill intent
let intent_data = create_anchor_bitcoin_fill_intent(
    "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
    U256::from(100000),
    U256::from(1000),
    1735689600,
)?;

// Submit via transaction to exit marketplace
// Intent ID will be: keccak256(creator || nonce || intent_data)

// Later, check intent status
let state = StateManager::new();
let intent_id = B256::from([/* calculated intent ID */]);

if let Some(intent) = state.get_intent(&intent_id) {
    match intent.status {
        IntentStatus::Submitted => println!("Awaiting solver"),
        IntentStatus::Locked(solver) => println!("Locked by {}", solver),
        IntentStatus::Solved => println!("Intent fulfilled"),
        IntentStatus::Cancelled => println!("Intent cancelled"),
    }
}

Build docs developers (and LLMs) love