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

# Membership

> Tracks membership status, joins/leaves, and membership counts.

```rust theme={null}
use sui::table;
```

<Tip>
  Explore this module further in the Mover Registry: @sage/shared
</Tip>

## Structs

### `Member`

Data that represents a single member of a larger organization.

```rust theme={null}
public struct Member has store
```

<Expandable title="Fields">
  ```rust theme={null}
    count: u64,
    created_at: u64,
    is_following: bool,
    member_type: u8,
    updated_at: u64
  ```
</Expandable>

### `Membership`

Table of individual members of an organization.

```rust theme={null}
public struct Membership has store
```

<Expandable title="Fields">
  ```rust theme={null}
    current_followers: u64,
    membership: sui::table::Table<address, Member>
  ```
</Expandable>

## Constants

Represents a wallet address.

```rust theme={null}
const WALLET: u8 = 0;
```

Represents an object address.

```rust theme={null}
const OBJECT: u8 = 1;
```

Represents a member addition.

```rust theme={null}
const MEMBER_ADD: u8 = 10;
```

Represents a member removal.

```rust theme={null}
const MEMBER_REMOVE: u8 = 11;
```

Error code when an address is already a member of an organization.

```rust theme={null}
const EIsMember: u64 = 370;
```

Error code when an address is not a member of an organization.

```rust theme={null}
const EIsNotMember: u64 = 371;
```

## Functions

### `assert_is_member`

Aborts with `EIsNotMember` if the address is not a member.

```rust theme={null}
public fun assert_is_member(membership: &Membership, member_address: address)
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun assert_is_member(
        membership: &Membership,
        member_address: address
    ) {
        let is_member = is_member(
            membership,
            member_address
        );

        assert!(is_member, EIsNotMember);
    }
  ```
</Expandable>

### `create`

Creates a new `Membership` instance.

```rust theme={null}
public fun create(ctx: &mut TxContext): Membership
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun create(
        ctx: &mut TxContext
    ): Membership {
        let membership = Membership {
            current_followers: 0,
            membership: table::new(ctx)
        };

        membership
    }
  ```
</Expandable>

### `get_count`

Get number of times the `Member` has joined the `Membership`.

```rust theme={null}
public fun get_count(membership: &Membership, member_address: address): u64
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun get_count(
        membership: &Membership,
        member_address: address
    ): u64 {
        membership.membership[member_address].count
    }
  ```
</Expandable>

### `get_created_at`

Get timestamp of when the `Member` first joined.

```rust theme={null}
public fun get_created_at(membership: &Membership, member_address: address): u64
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun get_created_at(
        membership: &Membership,
        member_address: address
    ): u64 {
        membership.membership[member_address].created_at
    }
  ```
</Expandable>

### `get_member_length`

Get the number of current `Member`s.

```rust theme={null}
public fun get_member_length(membership: &Membership): u64
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun get_member_length(
        membership: &Membership
    ): u64 {
        membership.current_followers
    }
  ```
</Expandable>

### `get_type`

Get whether the `Member` is an object or a wallet.

```rust theme={null}
public fun get_type(membership: &Membership, member_address: address): u8
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun get_type(
        membership: &Membership,
        member_address: address
    ): u8 {
        membership.membership[member_address].member_type
    }
  ```
</Expandable>

### `get_updated_at`

Get timestamp of when the `Membership` was most recently updated.

```rust theme={null}
public fun get_updated_at(membership: &Membership, member_address: address): u64
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun get_updated_at(
        membership: &Membership,
        member_address: address
    ): u64 {
        membership.membership[member_address].updated_at
    }
  ```
</Expandable>

### `is_member`

Returns true or false depending on whether the address is a `Member`.

```rust theme={null}
public fun is_member(membership: &Membership, member_address: address): bool
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun is_member(
        membership: &Membership,
        member_address: address
    ): bool {
        membership.membership.contains(member_address) &&
        membership.membership[member_address].is_following
    }
  ```
</Expandable>

### `object_join`

Join a `Membership` as an object.

```rust theme={null}
public fun object_join(membership: &mut Membership, obj_address: address, timestamp: u64): (u8, u8, u64)
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun object_join(
        membership: &mut Membership,
        obj_address: address,
        timestamp: u64
    ): (u8, u8, u64) {
        let count = join(
            membership,
            obj_address,
            OBJECT,
            timestamp
        );

        (MEMBER_ADD, OBJECT, count)
    }
  ```
</Expandable>

### `object_leave`

Leave a `Membership` as an object.

```rust theme={null}
public fun object_leave(membership: &mut Membership, obj_address: address, timestamp: u64): (u8, u8, u64)
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun object_leave(
        membership: &mut Membership,
        obj_address: address,
        timestamp: u64
    ): (u8, u8, u64) {
        let count = leave(
            membership,
            obj_address,
            timestamp
        );

        (MEMBER_REMOVE, OBJECT, count)
    }
  ```
</Expandable>

### `wallet_join`

Join a `Membership` as a wallet.

```rust theme={null}
public fun wallet_join(membership: &mut Membership, user_address: address, timestamp: u64 ): (u8, u8, u64)
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun wallet_join(
        membership: &mut Membership,
        user_address: address,
        timestamp: u64
    ): (u8, u8, u64) {
        let count = join(
            membership,
            user_address,
            WALLET,
            timestamp
        );

        (MEMBER_ADD, WALLET, count)
    }
  ```
</Expandable>

### `wallet_leave`

Leave a `Membership` as a wallet.

```rust theme={null}
public fun wallet_leave(membership: &mut Membership, user_address: address, timestamp: u64 ): (u8, u8, u64)
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun wallet_leave(
        membership: &mut Membership,
        user_address: address,
        timestamp: u64
    ): (u8, u8, u64) {
        let count = leave(
            membership,
            user_address,
            timestamp
        );

        (MEMBER_REMOVE, WALLET, count)
    }
  ```
</Expandable>
