Skip to main content

What is MandateClient?

MandateClient is the low-level API wrapper in the Mandate SDK. It maps 1:1 to the Mandate REST API: validate transactions, post events, poll intent status, and wait for approval decisions. Every method returns typed results and throws typed errors. Use MandateClient when your agent delegates signing to a separate wallet service (Bankr, Locus, Sponge) or when you need fine-grained control over the transaction lifecycle. If your agent holds its own private key, use MandateWallet instead: it wraps MandateClient and handles signing, broadcasting, and confirmation automatically.

Installation

Constructor

The MandateConfig interface accepts two fields:
Store the runtime key in an environment variable. Never hardcode it in source files or commit it to version control.

Static Methods

MandateClient.register(params)

Registers a new agent with Mandate. This is the only method that does not require authentication, because the agent does not have a runtime key yet.
Parameters: Returns a RegisterResult:
Example:
The claimUrl must be shared with the wallet owner. They visit it to link the agent to their dashboard account. Until claimed, the agent operates under default policies.

Instance Methods

client.validate(params)

The primary method for transaction validation. Sends the intended action to Mandate’s policy engine, which runs 14 sequential checks: circuit breaker, schedule, allowlist, blocked actions, per-transaction limits, daily and monthly quotas, risk screening, reputation scoring, reason scanning, and approval thresholds.
PreflightPayload:
PreflightResult:
Throws: Full example with error handling:
The reason field is required. Mandate scans it for prompt injection patterns and displays it to the wallet owner on approval requests. Write a clear, honest description of what the agent is doing and why.

client.preflight(params)

Backward-compatible alias for validate(). Same signature, same behavior, same return type.
Use validate() in new code. The preflight() method exists so older integrations continue to work without changes.

client.rawValidate(payload)

Deprecated. Use validate() for action-based validation. Raw validation is kept for legacy self-custodial flows but will be removed in a future version. MandateWallet uses this method internally: you do not need to call it directly.
Validates full EVM transaction parameters against the policy engine. Requires a precomputed intentHash that must match the server’s recomputation exactly.
IntentPayload:
ValidateResult:
Throws the same error classes as validate(): PolicyBlockedError, CircuitBreakerError, ApprovalRequiredError, RiskBlockedError.

client.postEvent(intentId, txHash)

Posts the broadcast transaction hash back to Mandate for envelope verification. Required after rawValidate() flows. The server compares the on-chain transaction against the validated parameters. If they do not match, the circuit breaker trips.
Parameters: Example:
Skipping postEvent() leaves the intent in broadcasted state indefinitely. The envelope verifier cannot confirm the transaction, and the intent will expire.

client.getStatus(intentId)

Returns the current state of an intent. Use this for one-off status checks. For continuous polling, use waitForApproval() or waitForConfirmation() instead.
IntentStatus:
See Intent States for a full diagram of state transitions and what triggers each one. Example:

client.waitForApproval(intentId, opts?)

Polls the intent status until the wallet owner approves, rejects, or the approval expires. Use this after catching an ApprovalRequiredError.
Parameters: Returns an IntentStatus with status: 'approved' or status: 'confirmed'. Throws MandateError if the approval is rejected (failed), expires (expired), or the polling timeout is exceeded. Example:

client.waitForConfirmation(intentId, opts?)

Polls the intent status until the transaction is confirmed on-chain. Use this after broadcasting a transaction to verify it landed.
Parameters: Returns an IntentStatus with status: 'confirmed', including the txHash, blockNumber, and gasUsed. Throws MandateError if the transaction fails, expires, or the polling timeout is exceeded. Example:

How does MandateClient compare to MandateWallet?

Use MandateClient when another service handles signing. Use MandateWallet when your agent holds its own key.

Sub-path Import

If you only need the client without the wallet (to avoid the viem dependency), use the sub-path export:
This import pulls in MandateClient and the error classes only. No viem, no signing utilities.

Next Steps

MandateWallet

High-level class that wraps MandateClient with local signing and broadcasting.

Error Classes

Full reference for PolicyBlockedError, CircuitBreakerError, and recovery patterns.

SDK Types

Complete TypeScript interfaces for all request and response objects.

Validate Transactions

Step-by-step guide for integrating validation into your agent loop.