SettleMint
Wallets

Multisig approvals

Create, inspect, and sign weighted multisig approvals for smart wallet user operations that need more signer weight before submission.

When a wallet has a multisig threshold configured, submitting a user operation immediately is not allowed. Instead, the integration creates an approval record that accumulates signatures from each required signer until the collected weight meets the threshold. The record stores the user operation hash, the call data to submit, the required weight, the collected weight, the lifecycle status, the optional deadline, and each collected signature.

Requires: advanced accounts enabled for the deployment.

This page is a reference for integration developers who already build smart wallet user operations. For changing the threshold itself, see Smart wallet multisig thresholds.

Prerequisites

Before creating or signing an approval:

  • The authenticated participant must have an active organisation.
  • The wallet must exist in the current system scope.
  • The wallet must have an installed weighted multisig validator.
  • The wallet must have a non-zero threshold configured.
  • The caller must sign as an active signer on that wallet.
  • The organisation must have a provisioned bundler wallet for account-abstraction submission.

Approval lifecycle

A multisig approval represents one pending user operation. You create the approval with the user operation hash and encoded call data. DALP records the initiator signature immediately, then stores the approval as pending unless the collected weight already meets the threshold.

Co-signers add signatures to the same approval. Each signature contributes the signer's configured weight. When the cumulative weight meets or exceeds the approval threshold, DALP marks the approval as submitted and submits the user operation automatically.

Approval statuses are:

StatusMeaning
pendingThe approval exists and still needs more signer weight, or it is waiting for submission.
submittedThe collected weight met the threshold and DALP submitted the user operation.
executedThe submitted user operation completed successfully.
expiredThe approval deadline passed before completion.
cancelledThe approval was cancelled without reaching the threshold.
failedSubmission or execution failed.

Create an approval

POST /api/v2/smart-wallets/{address}/approvals

Create an approval when your integration has built a user operation and needs co-signer weight before DALP submits it.

curl -X POST "https://your-platform.example.com/api/v2/smart-wallets/0x1234567890AbcdEF1234567890aBcdef12345678/approvals" \
  -H "X-Api-Key: YOUR_DALP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "userOpHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "callData": "0xabcdef",
    "description": "Approve signer rotation for the treasury smart wallet",
    "expiresAt": "2026-06-01T12:00:00Z"
  }'

The userOpHash must be a 32-byte hex hash. DALP rebuilds the operation preview from the supplied call data and wallet state, then rejects the request if the supplied hash does not match that preview.

The threshold request field is optional. DALP reads the current on-chain threshold from the indexed wallet state when it starts the approval workflow.

Use orderingScope only when the operation needs explicit submission ordering. The default is wallet-level ordering. When you set orderingScope to group, you must also provide a non-empty orderingKey; DALP rejects an orderingKey for any other scope.

List and read approvals

Use the list endpoint to show pending approvals and approval history for a wallet:

GET /api/v2/smart-wallets/{address}/approvals

The list endpoint is paginated. It supports filtering by status, initiatorAddress, operationKind, createdAt, and expiresAt. It supports sorting by status, operationKind, createdAt, and expiresAt; the default sort is newest first by createdAt.

Use the read endpoint when you already know the user operation hash:

GET /api/v2/smart-wallets/{address}/approvals/{userOpHash}

Both endpoints return approval records with collected signatures.

FieldTypeDescription
idstringApproval record ID.
userOpHashstringUser operation hash for the pending operation.
walletAddressEthereum addressSmart wallet contract address.
chainIdnumberChain ID for the approval.
organizationIdstringOrganization that owns the approval record.
initiatorAddressEthereum addressSigner that created the approval.
thresholdstringRequired cumulative signer weight as a decimal string.
currentWeightstringCollected signer weight as a decimal string.
callDatahex stringEncoded call data for the operation.
descriptionstring or nullOptional operation description.
statusenumApproval lifecycle status.
expiresAtISO 8601 string or nullOptional approval deadline.
createdAtISO 8601 stringCreation timestamp.
updatedAtISO 8601 stringLast update timestamp.
signaturesarrayCollected signer signatures with signer address, signature bytes, signer weight, and signing timestamp.

List responses use the standard { data, meta, links } collection envelope. Single approval reads use { data, links }.

Sign an approval

POST /api/v2/smart-wallets/{address}/approvals/{userOpHash}/sign

A co-signer signs an existing approval with an empty request body. DALP resolves the caller's signing address from the authenticated participant, verifies that the caller is an active signer on the wallet, records the signature once, and adds the signer's weight to the approval.

curl -X POST "https://your-platform.example.com/api/v2/smart-wallets/0x1234567890AbcdEF1234567890aBcdef12345678/approvals/0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/sign" \
  -H "X-Api-Key: YOUR_DALP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

If the signer already submitted a signature for that approval, DALP does not add duplicate weight. If the approval is expired or no longer pending, the sign request is rejected instead of reopening it. A submitted approval can still be signalled again while the platform continues the user operation submission. The sign endpoint returns the current record and does not create a second approval for the same hash.

Operational notes

  • Read the wallet and signer list before creating approvals so your integration can display the current threshold and signer weights.
  • Treat threshold and currentWeight as decimal strings because signer weights are integer values that can exceed JavaScript's safe number range.
  • Store userOpHash as the approval lookup key. The read and sign endpoints use it in the path.
  • Set expiresAt when the operation should not remain open indefinitely. Use an ISO 8601 date-time string.
  • Use group ordering only for operations that must share a sequencing lane. For ordinary wallet operations, omit orderingScope and orderingKey.
  • Do not ask co-signers to call owner-only wallet configuration endpoints directly. Route co-signer participation through the approval sign endpoint.

Error codes

When an approval operation fails, the API returns a stable DALP-NNNN error code. Use the code to decide whether the caller can correct the request and retry, whether to wait for the indexer to catch up, or whether the failure needs operator follow-up. Each code below maps to a canonical entry in the platform API error reference.

The tables list each code with its category, what triggers it, and the retry and idempotency semantics. idempotent means the same request can be sent again without side effects beyond the first attempt. retry once means the condition may clear on a subsequent call, such as after the indexer catches up. no retry means the caller must change the request, the signer, or the wallet state before the call will succeed. operator means the caller cannot fix the condition and should contact the operator.

Create an approval

These codes surface while you create an approval. Most are correctable from the caller side: select an organisation, sign in with an active signer, or rebuild the preview, then resend.

CodeCategoryRetry / idempotencyWhen it happens
DALP-0034permissionno retryNo active organisation on the session. Select an organisation before you create approvals.
DALP-0191permissionno retryThe session has no signer wallet configured. Sign in with a session that carries a valid signer wallet.
DALP-0209clientno retryThe wallet was not found. Verify the address and confirm the wallet has finished indexing.
DALP-0207clientno retryThe wallet has no multisig threshold configured. Set a threshold before you create approvals.
DALP-0178operationalno retryThe wallet has no installed weighted multisig validator. Install one before you create approvals.
DALP-0080clientno retrycallData or userOpHash did not match the API contract. callData must be a 0x-prefixed hex string, and userOpHash must be a 66-character 0x-prefixed hex hash. Correct the field and retry.
DALP-0196permissionno retryThe caller is not an active signer on the wallet's multisig validator. Only multisig signers can create approvals. This also fires when the active signer differs from the session's signing address; sign in with that signer to continue.
DALP-0204domainno retryuserOpHash does not match the preview DALP rebuilt from the supplied call data and wallet state. Rebuild the preview and retry.
DALP-0189clientno retryThe organisation has no provisioned bundler wallet. Complete system deployment first, because the provisioning phase creates the bundler wallet.
DALP-0201dependencyoperatorNo RPC URL is configured for the current chain. This needs operator follow-up on network configuration.
DALP-0281dependencyoperatorThe directory contract address is not configured in network config. This needs operator follow-up.
DALP-0282clientretry onceThe entry point was not found in the indexer for this system. Retry once the indexer has processed the directory state.
DALP-0013dependencyretry onceThe approval submission failed against a platform dependency. Retry the request; if it persists, contact support.
DALP-0185operationalretry onceThe approval workflow finished without enough data to build the response. Retry the request.

List and read approvals

These codes surface when you list a wallet's approvals or read a single approval. Both endpoints are restricted to wallet signers, so a non-signer cannot view approval data.

CodeCategoryRetry / idempotencyWhen it happens
DALP-0197permissionno retryThe caller is not a signer on the wallet. Only signers can list or view approval details.
DALP-0080clientno retryuserOpHash did not match the API contract. It must be a 66-character 0x-prefixed hex hash. Correct it and retry. (read only)
DALP-0181clientno retryNo approval exists for the supplied user operation hash. Verify the hash. (read only)
DALP-0182permissionno retryThe approval exists but does not belong to the wallet in the path. Read it under its own wallet address. (read only)

Sign an approval

These codes surface when a co-signer signs an approval. The sign route records each signer's weight once and never adds duplicate weight for a repeated signature.

CodeCategoryRetry / idempotencyWhen it happens
DALP-0080clientno retryuserOpHash did not match the API contract. It must be a 66-character 0x-prefixed hex hash. Correct it and retry.
DALP-0034permissionno retryNo active organisation on the session. Select an organisation before you sign approvals.
DALP-0190clientno retryThe session has no wallet ID configured. Sign in with a session that carries a valid wallet.
DALP-0208clientno retryThe wallet was not found. Verify the address and confirm the wallet has finished indexing.
DALP-0180operationalno retryThe wallet has no installed weighted multisig validator.
DALP-0195permissionno retryThe caller is not an active signer on the wallet's multisig validator, or the active signer differs from the session's signing address. Sign in with that signer.
DALP-0181clientno retryNo approval exists for the supplied user operation hash, or its stored preview state no longer reproduces the hash. Recreate the approval if the preview has drifted.
DALP-0184permissionno retryThe approval exists but does not belong to the wallet in the path. Cross-wallet signature submission is not allowed.
DALP-0024clientidempotentThe signature was not accepted. The approval may have already been signed by this signer, expired, or moved out of the pending state. This code also returns when the hash belongs to the bundler approval flow, which you co-sign through the bundler SDK client or UserOperation REST resource instead.
DALP-0281dependencyoperatorThe directory contract address is not configured in network config. This needs operator follow-up.
DALP-0282clientretry onceThe entry point was not found in the indexer for this system. Retry once the indexer has processed the directory state.

Fix client and permission codes from the caller side: correct the request, the signer identity, or the wallet scope, then retry. DALP-0024 on a repeat signature is expected and idempotent. DALP records each signer's weight only once and re-signals submission for an already-submitted approval rather than reopening it. DALP-0282 clears once the indexer catches up. DALP-0013, DALP-0201, and DALP-0281 are platform-side conditions that need operator follow-up rather than a request change.

On this page