# Flex Kit Attributes

Flex Kit attributes are non-primary attestations (e.g. not COUNTRY, AML, DID, etc) by an attestor on a subject. Any entity can be an attestor and can attest to any data points. Likewise, any single entity can query any attestation if they find it useful.

{% hint style="info" %}
You can see the implementation on [Github](https://github.com/QuadrataNetwork/passport-contracts/blob/develop/contracts/QuadFlexKit.sol).
{% endhint %}

#### setAttributes(bytes32 \_issuerAndAttr, bytes32 \_attrValue, address \_account, bytes calldata \_sigAccount)

Write an attestation about a given account. On initial call, `_sigAccount` is required and is the signature of the `_account` over the message:  `"I authorize [ISSUER_ADDRESS] to attest to my address [ACCOUNT_ADDRESS]"`

On subsequent calls, `_sigAccount` can be omitted.

```typescript
// Sign message from account authorizing issuer to post info about account
const msg = `I authorize ${issuer.address.toLowerCase()} to attest to my address ${account.address.toLowerCase()}`;
const sigAccount = await account.signMessage(msg);

// [Optional] If unknown, get the attribute key unique to the issuer
const attrKey = await flexKit
    .connect(issuer)
    getAttributeKey(issuer.address, ethers.utils.id("USER_TYPE"));

// Write that the account is of user_type "admin".
flexKit
  .connect(issuer)
  .setAttributes(
    attrKey,
    ethers.utils.id("ADMIN"),
    account.address,
    sigAccount
  )
```

#### setQueryFee(bytes32 \_rawAttrName, uint256 \_amount)

Set the query fee for a given attribute name. The input for attribute name must be the raw name (i.e. it must not be SHA3-256(ISSUER\_ADDR | RAW\_ATTR\_NAME).

#### setRevokedAttributes(bytes32 \_attrName, bool \_status)

Set write access for an issuer on a user's specific attribute name. This will default to false initially so once called, the user must continue to manage this boolean for the given issuer/attribute pair.

The input for attribute name must be the hashed value (i.e. SHA3-256(ISSUSER\_ADDR | RAW\_ATTR\_NAME).

#### withdraw()

Withdraw any funds from query fees.

#### getAttributeKey(address \_issuer, bytes32 \_attrName)

The attribute key is the hash of the issuer address and the attribute name. This ensure that multiple issuers can re-use the same attribute name without collision.

```
const attrKey = await flexKit
    .connect(issuer)
    getAttributeKey(issuer.address, ethers.utils.id("USER_TYPE"));
```

### Querying Attributes

The query functions are similar to the ones found in [Query attributes](/integration/how-to-integrate/query-attributes.md). The functions also accept primary attributes (i.e. COUNTRY, AML, DID, etc) and will fetch the results from the QuadReader.

####


---

# 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.quadrata.com/integration/additional-information/flex-kit-attributes.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.
