# Signing Object Conditions

{% hint style="warning" %}
TACo Action Control functionality is currently in Alpha and only available in the `DEVNET` environment.
{% endhint %}

Signing Object Conditions are a powerful way to validate 'internal' attributes of a transaction, request or attestation. For example, TACo Action Control nodes can only sign a UserOperation object if the proposed transaction involves whitelisted contract addresses. In general, TACo nodes are able to validate specific fields within signing request objects before collectively generating a threshold signature. Currently, two condition types are supported:

## `SigningObjectAttributeCondition`

Validatation of a **simple attribute**, such as a top-level field in the request object.

It is composed of the following properties:

* `attributeName`: The name of the attribute to inspect.
* `returnValueTest`: the test to validate the value extracted from the attribute of the object to sign.

### Example

Ensure the `callGasLimit` value for a `UserOperation` is less than 100,000 units of gas.

```typescript
import { conditions } from '@nucypher/taco';

const gasLimitRestriction = new conditions.base.signing.SigningObjectAttributeCondition({
  attributeName: 'callGasLimit',
  returnValueTest: {
    comparator: '<',
    value: 100000,
  },
});
```

## `SigningObjectAbiAttributeCondition`

Validation of ABI-encoded call data submitted for threshold signing (eg. a `UserOperation` 's `callData`) using human readable ABI signatures. This is useful when the object to sign represents a function call (e.g. a smart contract interaction) and one wishes to enforce constraints on the function being called and its arguments.

It is composed of the following properties:

* **`attributeName`**: The name of the field in the signing object containing the ABI-encoded data.
* **`abiValidation`**: See [`AbiCallValidation`](#abicallvalidation) below.

### AbiCallValidation

Defines which function signatures are allowed and what validations must apply to their parameters.

Key Fields:

* `allowedAbiCalls` : A mapping of human-readable ABI signatures (e.g., `"transfer(address,uint256)"`) to an array of `AbiParameterValidation` rules. At least one function signature entry must be defined.

### AbiParameterValidation

Specifies how to validate an individual parameter within the ABI-encoded call.

#### Key Fields:

* `parameterIndex`: zero-based index of the parameter to validate.
* `indexWithinTuple` *(Optional)*: If the value at `parameterIndex` is a tuple, the index of a value within the tuple, if applicable.
* `returnValueTest` *(Optional)*: the test to validate the value extracted from the `parameterIndex` / `indexWithinTuple` combination.
* `nestedAbiValidation` *(Optional)*: Recursively apply ABI call validation on the decoded `bytes` payload if applicable.

**Constraints:**

* Only one of `returnValueTest` or `nestedAbiValidation` may be set for a given parameter.
* Ensures correct Solidity types and validates that indices fall within expected bounds.

### **Example**

In this example, the authority wishes to constrain the threshold signing (and therefore execution) of a `UserOperation` for ERC-4337, such that TACo nodes will only produce signatures *if* the UserOps `callData` field is attempting to:\
(1) send an ERC-20 transfer of token at address `0x818E59818647700913Cf83f691dcC1b50Ac4864E` .\
(2) send an amount < `10000000000000000000` WEI.

Note: assume that the initial execution call data of the `UserOperation` for the smart contract wallet uses `execute(address,uint256,bytes)`.

```typescript
import { conditions } from '@nucypher/taco';

const callDataRestriction = new conditions.base.signing.SigningObjectAbiAttributeCondition({
  attributeName: 'callData',
  abiValidation: {
    allowedAbiCalls: {
      'execute(address,uint256,bytes)': [
        // check address of ERC-20 contract
        {
          parameterIndex: 0,
          returnValueTest: {
            comparator: '==',
            value: '0x818E59818647700913Cf83f691dcC1b50Ac4864E',
          },
        },
        // check bytes used for call to be made on ERC-20 contract
        {
          parameterIndex: 2,
          nestedAbiValidation: {
            allowedAbiCalls: {
              'transfer(address,uint256)': [
                {
                  parameterIndex: 1,
                  returnValueTest: {
                    comparator: '<',
                    value: 10000000000000000000,
                  },
                },
              ],
            },
          },
        },
      ],
    },
  },
});
```

## Implementation References

* Client-side:
  * <https://github.com/nucypher/taco-web/pull/670>
* Server-side:
  * <https://github.com/nucypher/nucypher/pull/3606>
  * <https://github.com/nucypher/nucypher/pull/3609>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.taco.build/for-developers/taco-sdk/references/conditions/signing-object-conditions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
