> ## 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.

# Key Concepts

>  

Before diving into advanced SDK usage, it’s important to understand a few key concepts and patterns central to Sage Protocol and its SDK. This section covers essential architectural and usage details to ensure a smooth integration process.

## Application Isolation and Context (`appId`)

Sage Protocol isolates content and interactions per application by using a unique identifier (`appId`). Each application maintains distinct channels and posts, while user identities and social graphs remain global across all Sage-compatible apps.

**What this means for you**:

* Users have a single, global identity and consistent social relationships everywhere.
* Each application provides tailored content and distinct community interactions..

**Example React Integration using appId**:

```typescript theme={null}
import { SageProvider } from '@sageprotocol/sdk/react';

const App = () => (
  <SageProvider
    appId="0x123..."                    // Your application's unique identifier
    channelRegistryId="0x456..."        // Registry managing channels specific to your app
    network="testnet"                   // 'mainnet' or 'testnet'
  >
    {/* Your app components */}
  </SageProvider>
);

export default App;
```

<Accordion title="Example Direct Javascript Integration using appId" icon="rectangle-code" iconType="sharp-solid">
  ```javascript theme={null}
  import { SageClient } from '@sageprotocol/sdk';

  const sageClient = new SageClient({
    appId: '0x123...',                    // Your application's unique identifier
    channelRegistryId: '0x456...',        // Registry managing channels specific to your app
    network: 'testnet'                    // 'mainnet' or 'testnet'
  });

  await sageClient.initialize();
  ```
</Accordion>

This structure demonstrates how applications utilize distinct contexts (`appId`) to maintain content isolation while benefiting from universal user identities.

## Invite-Based User Creation (Temporary)

Currently, Sage Protocol requires invite codes and keys for user creation. This temporary mechanism allows applications to control growth and maintain initial engagement quality.

* **Invite Code:** Unique code authorizing user creation.
* **Invite Key:** Secure key accompanying the invite code.

*(Note: Future protocol versions will make invite codes optional.)*

**Example React Hook for Creating Users with Invites:**

```typescript theme={null}
import { useUser } from '@sageprotocol/sdk/react';
import { useWallet } from '@suiet/wallet-kit';

function CreateUser() {
  const { create } = useUser();
  const { account, signAndExecuteTransaction } = useWallet();

  const handleCreateUser = async () => {
    const result = await create({
      amounts: [0, 0],
      avatar: 0,
      banner: 0,
      description: "Web3 enthusiast",
      inviteCode: "your-invite-code",
      inviteKey: "your-invite-key",
      name: "john-doe",
      self: account.address,
    });

    if (result.ok) {
      await signAndExecuteTransaction({ transaction: result.transaction });
      console.log("User successfully created!");
    } else {
      console.error(result.err);
    }
  };

  return <button onClick={handleCreateUser}>Create User</button>;
}

export default CreateUser;
```

<Accordion title="Example Direct JavaScript Integration for Creating Users with Invites" icon="rectangle-code" iconType="sharp-solid">
  ```javascript theme={null}
  const result = await sageClient.createUser({
    amounts: [0, 0],                            // required default amounts
    avatar: 0,                                  // optional avatar blob ID (default: 0)
    banner: 0,                                  // optional banner blob ID (default: 0)
    description: "Web3 enthusiast",             // profile description (markdown supported)
    inviteCode: "your-invite-code",             // required invite code
    inviteKey: "your-invite-key",               // required invite key
    name: "john-doe",                           // globally unique username
    self: walletAddress                         // user's wallet address
  });

  if (result.ok) {
    await signAndExecuteTransaction({ transaction: result.transaction });
    console.log("User successfully created!");
  } else {
    console.error(result.err);
  }
  ```
</Accordion>

## Transaction Patterns

Sage SDK operations involving blockchain transactions follow a two-step pattern:

1. **Construct Transaction:** SDK methods return transaction objects to be signed.
2. **Sign and Execute Transaction:** Your React app securely handles wallet interactions for transaction execution.

**Example transaction workflow in React:**

```typescript theme={null}
import { useUser } from '@sageprotocol/sdk/react';
import { useWallet } from '@suiet/wallet-kit';

const UserActionComponent = () => {
  const { create } = useUser();
  const { account, signAndExecuteTransaction } = useWallet();

  const handleAction = async () => {
    const result = await create({ /* parameters */ });

    if (result.ok) {
      await signAndExecuteTransaction({ transaction: result.transaction });
      console.log("Transaction executed successfully!");
    } else {
      console.error(result.err);
    }
  };

  return <button onClick={handleAction}>Perform Action</button>;
};

export default UserActionComponent;
```

<Accordion title="Example transaction workflow using direct JavaScript integration" icon="rectangle-code" iconType="sharp-solid">
  ```javascript theme={null}
  const result = await sageClient.someAction({ /* parameters */ });

  if (result.ok) {
    await signAndExecuteTransaction({ transaction: result.transaction });
    console.log("Transaction executed successfully!");
  } else {
    console.error(result.err);
  }
  ```

  Replace `someAction` with the specific method name you're invoking from `sageClient`. This accurately represents the direct JavaScript integration pattern documented in your SDK.
</Accordion>

This approach ensures secure, transparent blockchain interactions.

## Error Handling

The Sage SDK consistently provides structured results indicating success or errors. Every SDK call returns an object with:

* `ok`: Boolean indicating success (`true`) or failure (`false`).
* `err`: Error details if the call fails.

**Recommended React Error Handling Pattern:**

```javascript theme={null}
const result = await create({ /* parameters */ });

if (result.ok) {
  await signAndExecuteTransaction({ transaction: result.transaction });
  console.log("Success!");
} else {
  console.error("Error:", result.err);
}
```

Always verify transactions by checking the `ok` property before proceeding.

<Accordion title="Recommended Direct JavaScript Error Handling Pattern" icon="rectangle-code" iconType="sharp-solid">
  ```javascript theme={null}
  const result = await sageClient.someAction({ /* parameters */ });

  if (result.ok) {
    await signAndExecuteTransaction({ transaction: result.transaction });
    console.log("Success!");
  } else {
    console.error("Error:", result.err);
  }
  ```

  Replace `someAction` with the specific method you’re using from the `sageClient`.
</Accordion>

## Event Monitoring and Querying

The Sage SDK provides explicit event-monitoring capabilities. Events (e.g., user creation, posts, channel updates) are emitted on-chain, enabling your application to:

* React to user actions in real-time.
* Gather precise analytics and track activity.

**Example: Querying new user creation events using React hooks:**

```javascript theme={null}
import { useUser } from '@sageprotocol/sdk/react';

function UserEventsComponent() {
  const { queryCreateEvents } = useUser();

  const fetchEvents = async () => {
    const result = await queryCreateEvents({});

    result.events.forEach(event => {
      console.log(`New user created: ${event.userName} (User ID: ${event.userId})`);
      console.log(`Owned User ID: ${event.userOwnedId}, Shared User ID: ${event.userSharedId}`);
      if (event.referredBy) {
        console.log(`Referred by user ID: ${event.referredBy}`);
      }
    });

    if (result.hasNextPage) {
      const nextBatch = await queryCreateEvents({ cursor: result.nextCursor });
      // Process next batch similarly
    }
  };

  return <button onClick={fetchEvents}>Fetch New Users</button>;
}

export default UserEventsComponent;
```

<Accordion title="Example: Querying new user creation events using direct JavaScript integration" icon="rectangle-code" iconType="sharp-solid">
  ```javascript theme={null}
  // Monitor new user creation events
  const result = await sageClient.queryUserCreateEvents({});

  result.events.forEach(event => {
    console.log(`New user created: ${event.userName} (User ID: ${event.userId})`);
    console.log(`Owned User ID: ${event.userOwnedId}, Shared User ID: ${event.userSharedId}`);
    if (event.referredBy) {
      console.log(`Referred by user ID: ${event.referredBy}`);
    }
  });

  // Continue querying from the last event fetched
  if (result.hasNextPage) {
    const nextBatch = await sageClient.queryUserCreateEvents({
      cursor: result.nextCursor
    });
    // Process next batch similarly
  }
  ```
</Accordion>

## React Context and Hooks

For React apps, the Sage SDK provides built-in context (`SageProvider`) and custom hooks (`useUser`, `useChannel`, `usePost`) to simplify state management and interactions with blockchain primitives.

**Example: Following a channel using React hooks:**

```typescript theme={null}
import { useChannel } from '@sageprotocol/sdk/react';
import { useWallet } from '@suiet/wallet-kit';

function FollowChannel({ channelId, ownedUserId }) {
  const { follow } = useChannel();
  const { account, signAndExecuteTransaction } = useWallet();

  const handleFollow = async () => {
    const result = await follow({
      amounts: [0, 0],
      channelId,
      ownedUserId,
      self: account.address,
    });

    if (result.ok) {
      await signAndExecuteTransaction({ transaction: result.transaction });
      console.log("Channel followed successfully!");
    } else {
      console.error(result.err);
    }
  };

  return <button onClick={handleFollow}>Follow Channel</button>;
}

export default FollowChannel;
```

Leveraging these hooks ensures cleaner, more maintainable React code.

## Next Steps

With these key concepts clarified, you're now well-equipped to explore Sage SDK’s core primitives and fully utilize its powerful decentralized social functionalities. Proceed to:

* Learn detailed management of the core primitives:
  * [Users](#)
  * [Channels](#)
  * [Posts](#)
* [Advanced Guides](#): See complete examples for building sophisticated decentralized social apps.
* [**API Reference**](#): Explore comprehensive details on SDK methods and capabilities.
