# Amulets

Amulets give powers to those that hold them.

### Table of Contents

1. [KUTHULU Functions](#kuthulu-functions)
2. [Public Functions](#public-functions)
3. [Mult-Sig Functions](#multi-sig-functions)

***

## <mark style="color:purple;">KUTHULU Functions</mark>

### KuthuluHook

The `KuthuluHook` function can only be invoked by trusted contracts. It is used to mint a new Amulet if a post is considered as a "real post", having a non-zero `msgID`, exactly one tagged account (or two if `tipERC20Amount` is greater than zero), and the tagged account equals `vaultAddress`, and the tips received equals `costToMint`.

#### Inputs

| Name     | Type             | Description                                             |
| -------- | ---------------- | ------------------------------------------------------- |
| `newMsg` | `MsgData memory` | The struct containing the details about the new message |

#### Returns

| Name | Type   | Description                                      |
| ---- | ------ | ------------------------------------------------ |
|      | `bool` | Returns true if the function call was successful |

#### Example

```javascript
const ethers = require('ethers');

const newMsg = {
  msgID: 123,
  postedBy: [ethers.utils.getAddress('0xYourAddress1'), ethers.utils.getAddress('0xYourAddress2')],
  message: 'Hello World',
  paid: 10,
  hashtags: ['#hello', '#world'],
  taggedAccounts: [ethers.utils.getAddress('0xVaultAddress')],
  asGroup: 0,
  inGroups: [],
  uri: 'ipfs://QmYourURI',
  commentLevel: 0,
  isCommentOf: 0,
  isRepostOf: 0,
  msgStats: {
    likes: 5,
    comments: 2,
    reposts: 1,
    tipsReceived: 10,
    tipContract: ethers.utils.getAddress('0xTipContractAddress'),
    tipERC20Amount: 10,
    postByContract: 1,
    time: Date.now(),
    block: 12345678,
  },
};

await contract.KuthuluHook(newMsg);
```

***

## <mark style="color:purple;">Public Functions</mark>

### getWhaleSizes

The `getWhaleSizes` function is used to get a list of token amounts owned by any address.

#### Inputs

None

#### Returns

| Name | Type               | Description                                                           |
| ---- | ------------------ | --------------------------------------------------------------------- |
|      | `uint256[] memory` | Returns an array containing the number of tokens owned by any address |

#### Example

```javascript
const ethers = require('ethers');

await contract.getWhaleSizes();
```

### getWhales

The `getWhales` function is used to get the list of addresses that own a specific number of tokens.

#### Inputs

| Name    | Type      | Description                                    |
| ------- | --------- | ---------------------------------------------- |
| `level` | `uint256` | The number of tokens owned by a single address |

#### Returns

| Name | Type               | Description                                                                                  |
| ---- | ------------------ | -------------------------------------------------------------------------------------------- |
|      | `address[] memory` | Returns an array containing the addresses that own the number of tokens specified in `level` |

#### Example

```javascript
const ethers = require('ethers');

let level = 10;

await contract.getWhales(level);
```

### tokenURI

The `tokenURI` function is used to get the metadata of the token.

#### Inputs

| Name       | Type      | Description         |
| ---------- | --------- | ------------------- |
| `_tokenID` | `uint256` | The unique Group ID |

#### Returns

| Name | Type            | Description                                   |
| ---- | --------------- | --------------------------------------------- |
|      | `string memory` | Returns the metadata of the token as a string |

#### Example

```javascript
const ethers = require('ethers');

let _tokenID = 123;

await contract.tokenURI(_tokenID);
```

### getAmuletType

The `getAmuletType` function is used to get the type of amulet a token is by its ID.

#### Inputs

| Name       | Type      | Description         |
| ---------- | --------- | ------------------- |
| `amuletID` | `uint256` | The Amulet token ID |

#### Returns

| Name | Type               | Description                                                 |
| ---- | ------------------ | ----------------------------------------------------------- |
|      | `uint256[] memory` | Returns an array containing the badgeID and the amulet type |

#### Example

```javascript
const ethers = require('ethers');

let amuletID = 123;

await contract.getAmuletType(amuletID);
```

### kuthuluVerifyBadgeType

The `kuthuluVerifyBadgeType` function is used to verify if a badge type ID exists for the address invoking the function.

#### Inputs

| Name          | Type      | Description                 |
| ------------- | --------- | --------------------------- |
| `badgeTypeID` | `uint256` | The Badge type ID           |
| owner         | address   | Address of the badge holder |

#### Returns

| Name | Type   | Description                                                       |
| ---- | ------ | ----------------------------------------------------------------- |
|      | `bool` | Returns true if the badge type ID exists, otherwise returns false |

#### Example

```javascript
const ethers = require('ethers');

let badgeTypeID = 123;

await contract.kuthuluVerifyBadgeType(badgeTypeID);
```

***

## <mark style="color:purple;">Multi-Sig Functions</mark>

### addMultiSigLock

The `addMultiSigLock` function is used to add multi-signature address locking for transfers. The function can only be invoked by the token owner.

#### Inputs

| Name         | Type        | Description                                                  |
| ------------ | ----------- | ------------------------------------------------------------ |
| `tokenID`    | `uint256`   | The token's unique ID                                        |
| `_addresses` | `address[]` | The array of addresses required for multi-signature approval |

#### Returns

| Name | Type   | Description                                      |
| ---- | ------ | ------------------------------------------------ |
|      | `bool` | Returns true if the function call was successful |

#### Example

```javascript
const ethers = require('ethers');

let tokenID = 123;
let _addresses = [ethers.utils.getAddress('0xYourAddress1'), ethers.utils.getAddress('0xYourAddress2')];

await contract.addMultiSigLock(tokenID, _addresses);
```

### removeMultiSigLock

The `removeMultiSigLock` function is used to remove multi-signature address locking for transfers. The function can only be invoked by the token owner.

#### Inputs

| Name      | Type      | Description           |
| --------- | --------- | --------------------- |
| `tokenID` | `uint256` | The token's unique ID |

#### Returns

| Name | Type   | Description                                      |
| ---- | ------ | ------------------------------------------------ |
|      | `bool` | Returns true if the function call was successful |

#### Example

```javascript
const ethers = require('ethers');

let tokenID = 123;

await contract.removeMultiSigLock(tokenID);
```

### approveMultiSigTransfer

The `approveMultiSigTransfer` function is used to approve a multi-signature transfer for a token. The function can only be invoked by one of the addresses in the multi-signature array.

#### Inputs

| Name      | Type      | Description                                         |
| --------- | --------- | --------------------------------------------------- |
| `tokenID` | `uint256` | The token's unique ID                               |
| `to`      | `address` | The address to which the token is being transferred |

#### Returns

| Name | Type   | Description                                      |
| ---- | ------ | ------------------------------------------------ |
|      | `bool` | Returns true if the function call was successful |

#### Example

```javascript
const ethers = require('ethers');

let tokenID = 123;
let to = ethers.utils.getAddress('0xRecipientAddress');

await contract.approveMultiSigTransfer(tokenID, to);
```

### isMultiSigApproved

The `isMultiSigApproved` function is used to check if a multi-signature transfer for a token has been approved.

#### Inputs

| Name      | Type      | Description                                         |
| --------- | --------- | --------------------------------------------------- |
| `tokenID` | `uint256` | The token's unique ID                               |
| `to`      | `address` | The address to which the token is being transferred |

#### Returns

| Name | Type   | Description                                               |
| ---- | ------ | --------------------------------------------------------- |
|      | `bool` | Returns true if the transfer is approved, false otherwise |

#### Example

```javascript
const ethers = require('ethers');

let tokenID = 123;
let to = ethers.utils.getAddress('0xRecipientAddress');

await contract.isMultiSigApproved(tokenID, to);
```
