Admin Login
HomeGuidesAPI ReferenceChangelogBlockdaemon Main Docs
Log In
Guides

Transaction and approval flows

How intents, approvals, policy evaluation, MPC signing, and broadcasting fit together.

Institutional Vault applies policy evaluation to every operation, not just transfers. This includes administrative actions such as adding or updating users and groups, updating policy sets, and other configuration changes—each action is evaluated and enforced by 3 independent policy nodes before it can take effect.

Operation lifecycle

Security is enforced at the level of an operation: any task that requires the Policy Nodes to execute, such as signing a transaction. Policy can restrict who may initiate or approve an operation, or disallow it entirely. Every Policy Node enforces the policy independently, so enforcement remains correct as long as at least one node behaves correctly.

An operation passes through three phases:

  1. Initiation: A user (for example through the Wallet UI) or an API call with no initiator starts the operation. The Policy Nodes are not yet involved.
  2. Approval: Initiation produces an intent. The initiator confirms it if policy requires, and further approvals are collected as policy specifies.
  3. Execution: The Policy Nodes receive the intent, the approvals, and an unsigned transaction. Each node checks that the policy for the intent is fulfilled and that the unsigned transaction matches the intent. The nodes then sign the transaction together using an MPC protocol.

High-level transaction and approval flow

This is the high-level flow of submitting a transaction intent through Institutional Vault. Because approval signatures are decoupled from MPC transaction signatures, an arbitrary number of checkers—either programmatic Automated Approvers or human approvers—can be configured dynamically at runtime on a per-transaction basis. Automated Approvers are customer-configurable hooks: each runs your own conditional or business logic over the transaction (intent) data and returns an approval or rejection.

---
config:
    themeVariables:
        fontSize: 16px
        fontFamily: arial
        noteBkgColor: '#9370DB'
        noteTextColor: '#ffffff'
        noteBorderColor: '#4B0082'
---
sequenceDiagram
    autonumber

    participant Client as Wallet Client
    box rgba(147, 112, 219, 0.2) Institutional Vault
        participant MPA as MPC Policy Authority nodes<br>(3x MPA nodes)
    end
    participant BA1 as Automated Approver 1<br>(customer hook: custom logic)
    participant BA2 as Automated Approver 2<br>(customer hook: custom logic)
    actor Human as Human Approver 1<br/>(App / Device)

    Client->>MPA: submit transfer request
    activate MPA
    Note over MPA: Policy evaluation

    MPA->>BA1: request approval
    activate BA1
    BA1-->>MPA: approval signature
    deactivate BA1

    MPA->>BA2: request approval
    activate BA2
    BA2-->>MPA: approval signature
    deactivate BA2

    MPA->>Human: request approval
    activate Human
    Human-->>MPA: approval signature
    deactivate Human


    Note over MPA: MPC signing
    MPA-->>Client: tx signature
    deactivate MPA

End-to-end transaction flow

This is the programmatic flow for starting a transaction through the Vault API, including policy evaluation, confirmations, approvals, MPC signing, broadcasting, and operation status tracking. The client calls POST /api/cwp/operations/start/makeTransaction; Institutional Vault enriches the intent, evaluates policy, signs, and broadcasts to the network.

%%{init: {'themeVariables': { 'noteBkgColor': '#9370DB', 'noteTextColor': '#ffffff', 'noteBorderColor': '#4B0082' }}}%%
sequenceDiagram
    participant Client as Wallet Client
    participant Vault as Institutional Vault
    participant Blockchain as Blockchain Network

    Note over Client, Blockchain: 1. Start operation
    Client->>Vault: POST /api/cwp/operations/start/makeTransaction
    Vault->>Vault: Enrich intent and evaluate policy
    Vault-->>Client: Operation ID returned

    Note over Client, Blockchain: 2. Policy, confirmations, and approvals
    loop Until operation leaves pending states
        Client->>Vault: GET /api/cwp/operations/id/operationID/status
        Vault-->>Client: OperationStatus
        opt Confirmation or approval required
            Vault->>Vault: Collect initiator confirmation<br/>and approver signatures
        end
    end

    alt Policy blocks operation
        Vault-->>Client: Status Failed or blocked<br/>policy violation
    else Policy satisfied
        Note over Client, Blockchain: 3. MPC signing and broadcast
        Vault->>Vault: Threshold-sign transaction
        Vault->>+Blockchain: Broadcast signed transaction
        Blockchain-->>-Vault: Transaction hash
        Vault-->>Client: Status Succeeded<br/>tx hash in Result.Transaction.ID
    end

    Note over Client, Blockchain: 4. Final status
    Client->>Vault: GET /api/cwp/operations/id/operationID/status
    Vault-->>Client: Succeeded or Failed<br/>with Result or Error

Detailed Approval flow (intent signatures → MPC transaction signatures)

This Institutional Vault implements a MPC‑based wallet and policy engine where approvals
(intent‑level signatures) are cryptographically decoupled from MPC transaction signatures.
Approvers hold their own ECDSA P‑256 keys and sign intents, while policy nodes hold sharded
ECDSA/Ed25519 master keys and only sign validated transactions once policies are satisfied and
approvals are verified against a signed system state.

%%{init: {'themeVariables': { 'noteBkgColor': '#9370DB', 'noteTextColor': '#ffffff', 'noteBorderColor': '#4B0082' }}}%%
sequenceDiagram
    autonumber
    participant User as Approver<br/>(Approval Key)
    box rgba(147, 112, 219, 0.2) Institutional Vault
      participant Wallet as Wallet Service
      participant Policy as 3x Policy Nodes
      participant MPC as 3x MPC key shares
    end

    Wallet->>Wallet: StartOperation(intent)
    Wallet->>Wallet: Enrich intent and<br/>determine approvers
    loop For each approver
        Wallet->>User: Request approval<br/>(EnrichedIntent, MPASignature)
        User->>Wallet: Approve / reject intent<br/>(sign enriched intent)
        Wallet-->>Wallet: Store approval record<br/>(pubkey + signature)
    end
    Wallet->>Wallet: Build unsigned tx or forward RawTransaction
    Wallet->>Policy: Intent, approvals, and unsigned tx

    Policy->>Policy: Verify approvals against<br/>User table + ECDSA P‑256
    Policy->>Policy: Re‑evaluate policy using<br/>signed policies, users, groups
    alt Policy not satisfied
        Policy-->>Wallet: Error (missing / invalid approvals)
        note over Policy,Wallet: No MPC signatures produced
    else Policy satisfied
        Policy->>Policy: Parse unsigned bytes and<br/>check them against the intent
        Policy->>Policy: Rebuild signing payload<br/>from the parsed fields
        Policy->>MPC: Partial MPC-sign that hash
        MPC-->>Policy: Partial signatures
        Policy-->>Wallet: Signed transaction
    end

What you see is what you sign

An approval is an electronic signature over the intent. The approver's private key is held by the approver app, for example in secure storage on the approver's phone, and all important transaction data is shown explicitly to the approver before they sign. The Policy Nodes hold the public key of every user and verify each approval against it. Public keys are registered when the approver app is onboarded, at which point the key pair is generated and tied to the user through the authentication flow.

Guarantees and the signing boundary

  • Policies are enforced. Execution may depend on user approvals, and the Policy Nodes verify that execution matches what the users approved.
  • Enforcement is conservative. If a node cannot confirm the amount a transaction may transfer, it treats the amount as unbounded.
  • No single point of trust. Private keys are shared between nodes, and every node enforces policy.
  • Signing is the boundary. Once a transaction is signed, anyone who holds the signature can broadcast it, and Institutional Vault can no longer provide security guarantees for it. A transaction that should not proceed must therefore be stopped by policy or by an approver rejection before signing, not after.

Machine users as pre-signing gatekeepers

Inspection that is automated should happen before signing, by requiring approval from a machine user in policy. Institutional Vault does not distinguish between user types: a machine user simply holds a key pair, and its approval flow matches that of a human approver, except that it does not use the approver app. Typical examples:

  • A backend system that initiates an operation and then confirms it by signing the resulting intent after inspecting it.
  • A rate limiter that tracks amounts over time and withholds its signature until the transaction would stay within the configured limit.
  • A sanctions-screening service that approves only when every recipient is acceptable.

Because policy requires the machine user's signature before the nodes execute, and the nodes verify that execution matches the signed intent, no transaction is signed unless the gatekeeper has approved it. See Automated Approvals.

Where tampering is prevented

StageWhat is verifiedProtected by
ApprovalThe approver signed the exact intent they were shownApprover's ECDSA P-256 signature over the enriched intent
Execution: approvalsEach approval is from a registered userPolicy Nodes verify signatures against the signed User table
Execution: policyRequired approvals and restrictions are satisfiedEach Policy Node re-evaluates the signed policy independently
Execution: transactionThe unsigned transaction matches the approved intentEach Policy Node validates destinations, amounts, fees, and chain parameters
SigningOnly the validated transaction hash is signedThreshold MPC signature over sharded keys that are never reconstructed

Why this is cryptographically secure end‑to‑end

Decoupled key material

Approvals: Use per‑user or AutomatedApprover ECDSA P‑256 keys – for mobile approvers these are bound to OIDC identities at onboarding time, and for Automated Approvers they are provisioned by the wallet service. These users are stored in the signed User table.
Transactions: Use MPC ECDSA/Ed25519 master keys, sharded across policy nodes and never reconstructed; approver key compromise does not expose wallet keys.

Signed and verified system state

Core tables (Users, UserGroups, PolicySets, NodeInfos, tokens, etc.) are updated only via policy nodes, which sign each new generation with an MPC Ed25519 system-key.
Orchestrator cannot change policies or user/group membership without breaking these signatures; nodes verify them before using the data.
These signatures allow core tables to be stored in an untrusted database or orchestrator while still being verifiable by every policy node before use.

Node‑side policy enforcement

Policy nodes treat orchestrator data (including approvals) as untrusted inputs and:

  • Re‑verify every approval signature against the signed User table.
  • Re‑evaluate policies using the signed policy and group configuration.
  • Reject execution if any approval or confirmation is missing or invalid.

Intent-to-transaction binding

The Wallet Service builds the unsigned transaction after quorum, or forwards a client RawTransaction unchanged. Each Policy Node parses those bytes and checks the parsed transaction against the approved intent and its local signed tables. It then rebuilds the signing payload from the parsed fields and partial MPC-signs the hash of that reconstruction.

The node equality-checks chain id, destination, amount, and calldata. When Gas, MaxPriorityFeePerGas, MaxFeePerGas, or Nonce is set on the intent, it equality-checks only the first of those fields that is set. A raw transaction that cannot be decoded fails before any MPC signature.


Did this page help you?