> ## Documentation Index
> Fetch the complete documentation index at: https://docs.story.foundation/llms.txt
> Use this file to discover all available pages before exploring further.

# Group

> GroupClient allows you to create groups and add IP Assets to them.

## GroupClient

### Methods

* registerGroup
* mintAndRegisterIpAndAttachLicenseAndAddToGroup
* registerIpAndAttachLicenseAndAddToGroup
* registerGroupAndAttachLicense
* registerGroupAndAttachLicenseAndAddIps
* collectAndDistributeGroupRoyalties
* addIpsToGroup
* getClaimableReward
* removeIpsFromGroup
* claimReward
* collectRoyalties

### registerGroup

Registers a Group IPA.

| Method          | Type                                                                |
| --------------- | ------------------------------------------------------------------- |
| `registerGroup` | `(request: RegisterGroupRequest) => Promise<RegisterGroupResponse>` |

Parameters:

* `request.groupPool`: The address specifying how royalty will be split amongst the pool of IPs in the group.

```typescript Response Type theme={null}
export type RegisterGroupResponse = {
  txHash?: Hex;
  encodedTxData?: EncodedTxData;
  groupId?: Address;
};
```

### mintAndRegisterIpAndAttachLicenseAndAddToGroup

Mint an NFT from a SPGNFT collection, register it with metadata as an IP, attach license terms to the registered IP, and add it to a group IP.

| Method                                           | Type                                                                                                                                  |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `mintAndRegisterIpAndAttachLicenseAndAddToGroup` | `(request: MintAndRegisterIpAndAttachLicenseAndAddToGroupRequest) => Promise<MintAndRegisterIpAndAttachLicenseAndAddToGroupResponse>` |

Parameters:

* `request.nftContract`: The address of the NFT collection.
* `request.groupId`: The ID of the group IP to add the newly registered IP.
* `request.licenseTermsId`: The ID of the registered license terms that will be attached to the new IP.
* `request.recipient`: \[Optional] The address of the recipient of the minted NFT,default value is your wallet address.
* `request.licenseTemplate`: \[Optional] The address of the license template to be attached to the new group IP,default value is Programmable IP License.
* `request.deadline`: \[Optional] The deadline for the signature in milliseconds,default value is 1000ms.
* `request.ipMetadata`: \[Optional] The desired metadata for the newly minted NFT and newly registered IP.
  * `request.ipMetadata.ipMetadataURI` \[Optional] The URI of the metadata for the IP.
  * `request.ipMetadata.ipMetadataHash` \[Optional] The hash of the metadata for the IP.
  * `request.ipMetadata.nftMetadataURI` \[Optional] The URI of the metadata for the NFT.
  * `request.ipMetadata.nftMetadataHash` \[Optional] The hash of the metadata for the IP NFT.

```typescript Response Type theme={null}
export type MintAndRegisterIpAndAttachLicenseAndAddToGroupResponse = {
  txHash?: Hex;
  encodedTxData?: EncodedTxData;
  ipId?: Address;
  tokenId?: bigint;
};
```

### registerIpAndAttachLicenseAndAddToGroup

Register an NFT as IP with metadata, attach license terms to the registered IP, and add it to a group IP.

| Method                                    | Type                                                                                                                    |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `registerIpAndAttachLicenseAndAddToGroup` | `(request: RegisterIpAndAttachLicenseAndAddToGroupRequest) => Promise<RegisterIpAndAttachLicenseAndAddToGroupResponse>` |

Parameters:

* `request.spgNftContract`: The address of the NFT collection.
* `request.tokenId`: The ID of the NFT.
* `request.groupId`: The ID of the group IP to add the newly registered IP.
* `request.licenseTermsId`: The ID of the registered license terms that will be attached to the new IP.
* `request.licenseTemplate`: \[Optional] The address of the license template to be attached to the new group IP, default value is Programmable IP License.
* `request.deadline`: \[Optional] The deadline for the signature in milliseconds, default is 1000ms.
* `request.ipMetadata`: \[Optional] The desired metadata for the newly minted NFT and newly registered IP.
  * `request.ipMetadata.ipMetadataURI` \[Optional] The URI of the metadata for the IP.
  * `request.ipMetadata.ipMetadataHash` \[Optional] The hash of the metadata for the IP.
  * `request.ipMetadata.nftMetadataURI` \[Optional] The URI of the metadata for the NFT.
  * `request.ipMetadata.nftMetadataHash` \[Optional] The hash of the metadata for the IP NFT.

```typescript Response Type theme={null}
export type RegisterIpAndAttachLicenseAndAddToGroupResponse = {
  txHash?: Hex;
  encodedTxData?: EncodedTxData;
  ipId?: Address;
  tokenId?: bigint;
};
```

### registerGroupAndAttachLicense

Register a group IP with a group reward pool and attach license terms to the group IP.

| Method                          | Type                                                                                                |
| ------------------------------- | --------------------------------------------------------------------------------------------------- |
| `registerGroupAndAttachLicense` | `(request: RegisterGroupAndAttachLicenseRequest) => Promise<RegisterGroupAndAttachLicenseResponse>` |

Parameters:

* `request.groupPool`: The address specifying how royalty will be split amongst the pool of IPs in the group.
* `request.licenseTermsId`: The ID of the registered license terms that will be attached to the new group IP.
* `request.licenseTemplate`: \[Optional] The address of the license template to be attached to the new group IP, default value is Programmable IP License.

```typescript Response Type theme={null}
export type RegisterGroupAndAttachLicenseResponse = {
  txHash?: Hex;
  encodedTxData?: EncodedTxData;
  groupId?: Address;
};
```

### registerGroupAndAttachLicenseAndAddIps

Register a group IP with a group reward pool, attach license terms to the group IP, and add individual IPs to the group IP.

| Method                                   | Type                                                                                                                  |
| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `registerGroupAndAttachLicenseAndAddIps` | `(request: RegisterGroupAndAttachLicenseAndAddIpsRequest) => Promise<RegisterGroupAndAttachLicenseAndAddIpsResponse>` |

Parameters:

* `request.ipIds`: The IP IDs of the IPs to be added to the group.
* `request.groupPool`: The address specifying how royalty will be split amongst the pool of IPs in the group.
* `request.maxAllowedRevShare`: The maximum reward share percentage that can be allocated to each member IP.
* `request.licenseData`: The data of the license and its configuration to be attached to the new group IP.
  * `request.licenseData.licenseTermsId`: The ID of the registered license terms that will be attached to the new group IP.
  * `request.licenseData.licensingConfig`: \[Optional] See the [LicensingConfig type](https://github.com/storyprotocol/sdk/blob/main/packages/core-sdk/src/types/common.ts#L15). If none provided, it will default to the one shown [here](https://github.com/storyprotocol/sdk/blob/main/packages/core-sdk/src/utils/validateLicenseConfig.ts).
  * `request.licenseData.licenseTemplate`: \[Optional] The address of the license template to be attached to the new group IP, default value is Programmable IP License.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const response =
    await client.groupClient.registerGroupAndAttachLicenseAndAddIps({
      groupPool: "0xf96f2c30b41Cb6e0290de43C8528ae83d4f33F89", // EvenSplitGroupPool from https://docs.story.foundation/docs/deployed-smart-contracts
      maxAllowedRewardShare: 5,
      ipIds: ["0x01"],
      licenseData: {
        licenseTermsId: "5",
      },
    });
  ```

  ```typescript Request Type theme={null}
  export type RegisterGroupAndAttachLicenseAndAddIpsRequest = {
    groupPool: Address;
    ipIds: Address[];
    licenseData: LicenseData;
    maxAllowedRewardShare: number | string;
  };
  ```

  ```typescript Response Type theme={null}
  export type RegisterGroupAndAttachLicenseAndAddIpsResponse = {
    txHash?: Hex;
    encodedTxData?: EncodedTxData;
    groupId?: Address;
  };
  ```
</CodeGroup>

### collectAndDistributeGroupRoyalties

Collect royalties for the entire group and distribute the rewards to each member IP's royalty vault.

| Method                               | Type                                                                                                          |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| `collectAndDistributeGroupRoyalties` | `(request: CollectAndDistributeGroupRoyaltiesRequest) => Promise<CollectAndDistributeGroupRoyaltiesResponse>` |

Parameters:

* `request.groupIpId`: The IP ID of the group.
* `request.currencyTokens`: The addresses of the currency (revenue) tokens to claim.
* `request.memberIpIds`: The IDs of the member IPs to distribute the rewards to.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { WIP_TOKEN_ADDRESS } from "@story-protocol/core-sdk";

  const response = await client.groupClient.collectAndDistributeGroupRoyalties({
    groupIpId: "0x01",
    currencyTokens: [WIP_TOKEN_ADDRESS],
    memberIpIds: ["0x02"],
  });
  ```

  ```typescript Request Type theme={null}
  export type CollectAndDistributeGroupRoyaltiesRequest = {
    groupIpId: Address;
    currencyTokens: Address[];
    memberIpIds: Address[];
  };
  ```

  ```typescript Response Type theme={null}
  export type CollectAndDistributeGroupRoyaltiesResponse = {
    txHash: Hash;
    receipts?: TransactionReceipt[];
    collectedRoyalties?: Omit<
      GroupingModuleCollectedRoyaltiesToGroupPoolEvent,
      "pool"
    >[];
    royaltiesDistributed?: {
      ipId: Address;
      amount: bigint;
      token: Address;
      /**
       * Amount after the fee to the royalty module treasury.
       */
      amountAfterFee: bigint;
    }[];
  };
  ```
</CodeGroup>

### addIpsToGroup

Adds IPs to a group. The function must be called by the Group IP owner or an authorized operator.

| Method          | Type                                                      |
| --------------- | --------------------------------------------------------- |
| `addIpsToGroup` | `(request: AddIpRequest) => Promise<TransactionResponse>` |

Parameters:

* `request.groupIpId`: The ID of the group IP to add the IPs to.
* `request.ipIds`: The addresses of the IPs to add to the Group IP. IP IDs must be attached to the group IP license terms.
* `request.maxAllowedRewardSharePercentage`: \[Optional] The maximum reward share percentage that can be allocated to each member IP. Must be between 0 and 100 (where 100% represents 100\_000\_000). Default is 100.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const response = await client.groupClient.addIpsToGroup({
    groupIpId: "0x01",
    ipIds: ["0x02", "0x03"],
  });
  ```

  ```typescript Request Type theme={null}
  export type AddIpRequest = {
    groupIpId: Address;
    ipIds: Address[];
    maxAllowedRewardSharePercentage?: number;
  };
  ```

  ```typescript Response Type theme={null}
  export type TransactionResponse = {
    txHash: Hash;
    receipt?: TransactionReceipt;
  };
  ```
</CodeGroup>

### getClaimableReward

Returns the available reward for each IP in the group.

| Method               | Type                                                        |
| -------------------- | ----------------------------------------------------------- |
| `getClaimableReward` | `(request: GetClaimableRewardRequest) => Promise<bigint[]>` |

Parameters:

* `request.groupIpId`: The ID of the group IP.
* `request.currencyToken`: The address of the currency (revenue) token to check.
* `request.memberIpIds`: The IDs of the member IPs to check rewards for.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { WIP_TOKEN_ADDRESS } from "@story-protocol/core-sdk";

  const rewards = await client.groupClient.getClaimableReward({
    groupIpId: "0x01",
    currencyToken: WIP_TOKEN_ADDRESS,
    memberIpIds: ["0x02", "0x03"],
  });
  ```

  ```typescript Request Type theme={null}
  export type GetClaimableRewardRequest = {
    groupIpId: Address;
    currencyToken: Address;
    memberIpIds: Address[];
  };
  ```

  ```typescript Response Type theme={null}
  // Returns an array of bigint values representing the claimable reward amount for each member IP
  type Response = bigint[];
  ```
</CodeGroup>

### removeIpsFromGroup

Removes IPs from a group. The function must be called by the Group IP owner or an authorized operator.

| Method               | Type                                                                   |
| -------------------- | ---------------------------------------------------------------------- |
| `removeIpsFromGroup` | `(request: RemoveIpsFromGroupRequest) => Promise<TransactionResponse>` |

Parameters:

* `request.groupIpId`: The ID of the group IP to remove the IPs from.
* `request.ipIds`: The addresses of the IPs to remove from the Group IP.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const response = await client.groupClient.removeIpsFromGroup({
    groupIpId: "0x01",
    ipIds: ["0x02", "0x03"],
  });
  ```

  ```typescript Request Type theme={null}
  export type RemoveIpsFromGroupRequest = {
    groupIpId: Address;
    ipIds: Address[];
  };
  ```

  ```typescript Response Type theme={null}
  export type TransactionResponse = {
    txHash: Hash;
    receipt?: TransactionReceipt;
  };
  ```
</CodeGroup>

### claimReward

Claims reward for member IPs in a group. Emits an on-chain [ClaimedReward](https://github.com/storyprotocol/protocol-core-v1/blob/v1.3.1/contracts/interfaces/modules/grouping/IGroupingModule.sol#L31) event.

| Method        | Type                                                            |
| ------------- | --------------------------------------------------------------- |
| `claimReward` | `(request: ClaimRewardRequest) => Promise<ClaimRewardResponse>` |

Parameters:

* `request.groupIpId`: The ID of the group IP.
* `request.currencyToken`: The address of the currency (revenue) token to claim.
* `request.memberIpIds`: The IDs of the member IPs to distribute the rewards to.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { WIP_TOKEN_ADDRESS } from "@story-protocol/core-sdk";

  const response = await client.groupClient.claimReward({
    groupIpId: "0x01",
    currencyToken: WIP_TOKEN_ADDRESS,
    memberIpIds: ["0x02", "0x03"],
  });
  ```

  ```typescript Request Type theme={null}
  export type ClaimRewardRequest = {
    groupIpId: Address;
    currencyToken: Address;
    memberIpIds: Address[];
  };
  ```

  ```typescript Response Type theme={null}
  export type ClaimRewardResponse = {
    txHash: Hash;
    claimedReward?: GroupingModuleClaimedRewardEvent[];
  };
  ```
</CodeGroup>

### collectRoyalties

Collects royalties into the pool, making them claimable by group member IPs. Emits an on-chain [CollectedRoyaltiesToGroupPool](https://github.com/storyprotocol/protocol-core-v1/blob/v1.3.1/contracts/interfaces/modules/grouping/IGroupingModule.sol#L38) event.

| Method             | Type                                                                      |
| ------------------ | ------------------------------------------------------------------------- |
| `collectRoyalties` | `(request: CollectRoyaltiesRequest) => Promise<CollectRoyaltiesResponse>` |

Parameters:

* `request.groupIpId`: The ID of the group IP.
* `request.currencyToken`: The address of the currency (revenue) token to collect.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { WIP_TOKEN_ADDRESS } from "@story-protocol/core-sdk";

  const response = await client.groupClient.collectRoyalties({
    groupIpId: "0x01",
    currencyToken: WIP_TOKEN_ADDRESS,
  });
  ```

  ```typescript Request Type theme={null}
  export type CollectRoyaltiesRequest = {
    groupIpId: Address;
    currencyToken: Address;
  };
  ```

  ```typescript Response Type theme={null}
  export type CollectRoyaltiesResponse = {
    txHash: Hash;
    collectedRoyalties?: bigint;
  };
  ```
</CodeGroup>
