# 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](../how-to-integrate/query-attributes). The functions also accept primary attributes (i.e. COUNTRY, AML, DID, etc) and will fetch the results from the QuadReader.

####

