How to use intentguard

This guide explains how a protocol team can use intentguard in operations. It is written for developers, security councils, and governance operators.

Status: reference implementation, unaudited. Use this to prototype, review, and adapt. Do not secure real funds with it before independent audit and protocol-specific tests.

The idea in one minute

Intentguard sits between your council/multisig and dangerous protocol actions.

Instead of letting signers approve opaque transaction bytes, each privileged action becomes a proposal with:

If the transaction does not match the intent, it cannot execute. If the signatures are stale, it cannot queue. If signers notice something wrong during the cool-off, they can cancel it.

What to protect first

Start with actions where one bad transaction can damage users:

Do not start with every function. Start with the functions that move power.

How realistic is integration?

For most EVM protocols, this is realistic as a Safe module or guarded-owner pattern. The hard work is not deploying the module. The hard work is removing direct admin bypass and writing adapters for each sensitive action.

For most Solana protocols, this is realistic when admin authority is already separated into clear instructions or PDAs. It is harder when admin authority is spread across many programs, when instructions have complex account-dependent effects, or when the protocol relies on fast manual intervention.

Rough adoption estimates:

Good first integrations:

Harder integrations:

Roles

One person can hold more than one role, but the operational process should treat them separately.

The lifecycle

1. Define the action schema

For each protected action, define exactly what signers are approving.

Example:

WhitelistCollateral {
  target: RiskManager,
  token: CVT,
  oracle: Chainlink/CVT-USD,
  fair_value_usd: 1.00,
  max_deposit_usd: 500000,
  max_ltv_bps: 0,
  expires_at: 2026-04-30T18:00:00Z
}

The schema should include every field that would matter to a signer. If a field changes the risk, it belongs in the intent.

2. Write an adapter

The adapter decodes the actual transaction and recomputes the canonical intent hash.

For EVM, see:

contracts/CollateralListingAdapter.sol

For Solana, adapters are protocol-specific because account layouts and instructions vary. The Solana program includes the guard state machine, but each integration still needs a strict decoder for its own instructions.

Adapter rule: unknown or ambiguous calls fail closed.

3. Configure the vault

Pick operational parameters:

quorumM: 3
signersN: 5
vetoK: 2
freshWindow: 10 minutes
cooloff: 24 hours
executeDelay: 60 seconds
proposalLifetime: 48 hours

Recommended defaults:

4. Draft a proposal

A developer or operator creates the proposal:

The system computes:

5. Review and sign

Each signer reviews the rendered intent, not raw bytes.

The signer should see:

The signer then signs a fresh attestation. Old attestations should be useless.

The signer CLI sketch is here:

clients/signer-cli.ts

For higher-value protocols, add a separate attester device or locked-down attester app. The attester renders the same intent on a device that is not the signer’s laptop and produces a co-signature. See attester/.

6. Queue

Once the proposal has enough fresh signatures, it enters the public queue.

From this point, monitors should alert:

The queue is the defense. If nobody watches it, the cool-off loses most of its value.

7. Veto or alarm

During the cool-off:

Cancel if:

8. Execute

After the cool-off and execute delay:

Only then does it call the protected contract/program.

EVM tutorial

Use this flow when the protected authority is a Safe or Safe-like multisig.

Step 1: Install tools

You need Foundry:

curl -L https://foundry.paradigm.xyz | bash
foundryup

Then from the repo:

cd /Users/uwecerron/Desktop/primitive/evm
forge test

Step 2: Deploy the module

Deploy the Safe module implementation in:

evm/src/IntentGuardModule.sol

Constructor parameters:

safe_: Safe address
quorumM_: approvals required
vetoK_: cancellations required
freshWindow_: max signer freshness
cooloff_: public waiting period
oracleToleranceBps_: oracle deviation tolerance
oracleMaxStaleness_: max oracle staleness

Step 3: Enable it on the Safe

Use the Safe UI or Safe transaction builder to enable the module.

Important: enabling a module is not enough. The protected protocol must not still accept direct Safe calls for guarded functions.

Use one of these patterns:

Step 4: Draft a proposal

For a simple parameter call:

bytes memory data = abi.encodeWithSelector(
    RiskManager.setLtv.selector,
    token,
    newLtvBps
);

Draft through the module:

uint64 id = module.draftProposal(
    ACTION_SET_LTV,
    address(riskManager),
    0,
    data,
    0,
    address(0)
);

For oracle-bound actions, include the claimed value and oracle address.

Step 5: Sign

Each Safe owner reviews the rendered intent and calls:

module.attest(id, intentHashWitness, uint64(block.timestamp));

The important field is intentHashWitness: the signer should only submit the hash they reviewed in the signer UI.

Step 6: Monitor

Watch:

ProposalDrafted
ProposalSigned
ProposalQueued
ProposalAlarm
ProposalCancelled
ProposalExecuted
ProposalRejected

Alert humans when ProposalQueued fires.

Step 7: Cancel if needed

Any Safe owner can call:

module.cancel(id);

Once vetoK owners cancel, execution is blocked.

Step 8: Execute

After cooloff + executeDelay:

module.execute(id);

If the oracle is stale, the claim deviates, the nonce changed, or the proposal was cancelled, execution fails.

Solana tutorial

Use this flow when the protected authority is a Solana program authority, upgrade authority, treasury PDA, or council PDA.

Step 1: Install tools

You need Rust, Solana CLI, and Anchor:

sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"
cargo install --git https://github.com/coral-xyz/anchor avm --locked
avm install latest
avm use latest

Then from the repo:

cd /Users/uwecerron/Desktop/primitive/solana
anchor test

Step 2: Initialize a vault

Create one vault per protected authority.

Example protected authorities:

The vault config contains:

Step 3: Transfer authority

Move the protected authority to the intentguard vault PDA.

This is the key step. If the old admin key can still call the protocol directly, intentguard is only advisory.

Step 4: Draft and queue proposals

A proposal includes:

Signers produce ed25519 attestations over the proposal fields. The guard checks those attestations before queueing.

Step 5: Monitor and cancel

Watch program logs/events for queued proposals.

If something is wrong, signers call cancel. Once veto_threshold distinct signers cancel, the proposal cannot execute.

Step 6: Execute by CPI

After the cool-off and execute delay, the program executes the queued instruction by CPI using the vault PDA.

Before production use, replace any scaffolded adapter or ed25519 parsing logic with strict protocol-specific validation.

Signer tutorial

A signer should never be asked to approve raw bytes.

The signer UI should show:

Action: WhitelistCollateral
Token: CVT
Oracle: Chainlink/CVT-USD
Claimed price: $1.00
Live price: $0.0001
Max deposit: $500,000,000
Target: 0x...
Nonce: 12
Expires: 2026-04-30 18:00 UTC

If anything looks wrong, do not sign. Raise an alarm or cancel.

A good signer flow:

  1. Open the proposal from a trusted queue UI.
  2. Verify it was announced in the expected governance/security channel.
  3. Compare target addresses against an address book.
  4. Check oracle feeds and caps.
  5. Type the action kind to confirm.
  6. Sign only if the displayed intent is correct.

Operations runbook

For every queued proposal:

  1. Post it to the council channel.
  2. Alert all signers out-of-band.
  3. Compare target addresses against an address book.
  4. Compare calldata/instruction hash against the reviewed build or script.
  5. Check oracle feed identity, staleness, and deviation.
  6. Wait through the cool-off.
  7. Execute only from the expected operator account.
  8. Archive proposal, signatures, intent render, and execution transaction.

First integration target

The best first protected action is usually not upgrades. Start with something easy to decode and high impact:

Once that path is tested, add upgrades and admin transfers.

What not to do

Minimal production acceptance checklist

Before mainnet: