> ## Documentation Index
> Fetch the complete documentation index at: https://ixoworld-mintlify-9a7944b6.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Implementation examples

> Worked end-to-end TypeScript examples for IXO MultiClient SDK and IXO Matrix Client SDK.

These examples follow the canonical patterns from the [`@ixo/impactxclient-sdk`](https://www.npmjs.com/package/@ixo/impactxclient-sdk) and [`@ixo/matrixclient-sdk`](https://www.npmjs.com/package/@ixo/matrixclient-sdk) READMEs. Use them as starting templates — exact field shapes are generated from the [chain proto definitions](https://github.com/ixofoundation/ixo-blockchain/tree/main/proto/ixo).

For the step-by-step explanation behind each pattern, read [Developer workflows](/guides/dev/workflows) first.

## Setup

```bash theme={null}
npm install @ixo/impactxclient-sdk @ixo/matrixclient-sdk
```

```ts theme={null}
import {
  ixo,
  createQueryClient,
  createSigningClient,
} from "@ixo/impactxclient-sdk";

import {
  createMatrixApiClient,
  createMatrixRoomBotClient,
  createMatrixStateBotClient,
  createMatrixClaimBotClient,
} from "@ixo/matrixclient-sdk";

const RPC_ENDPOINT = "https://rpc.ixo.world";
const HOME_SERVER_URL = "https://devmx.ixo.earth";

const queryClient = await createQueryClient(RPC_ENDPOINT);
const signingClient = await createSigningClient(RPC_ENDPOINT, offlineSigner);
```

## Digital twin: create an entity

```ts theme={null}
const createEntity = async (signerAddress: string) => {
  const message = {
    typeUrl: "/ixo.entity.v1beta1.MsgCreateEntity",
    value: ixo.entity.v1beta1.MsgCreateEntity.fromPartial({
      ownerAddress: signerAddress,
      entityType: "asset",
      context: [
        ixo.iid.v1beta1.Context.fromPartial({
          key: "class",
          val: "did:ixo:entity:protocol123",
        }),
      ],
      verification: [],
      controller: [],
      service: [],
      linkedResource: [],
      accordedRight: [],
      linkedEntity: [],
      linkedClaim: [],
    }),
  };

  return signingClient.signAndBroadcast(signerAddress, [message], "auto");
};

const entities = await queryClient.ixo.entity.v1beta1.entityList();
```

## Source an entity room (IXO Matrix)

Each entity has an associated encrypted Matrix room — its data room. Source it with the room bot, which creates the room if needed and invites the caller.

```ts theme={null}
const matrixRoomBotClient = createMatrixRoomBotClient({
  homeServerUrl: HOME_SERVER_URL,
  botUrl: "https://devmx.ixo.earth/bots/room",
  accessToken: matrixAccessToken,
});

const sourceRoomResponse = await matrixRoomBotClient.room.v1beta1.sourceRoomAndJoin(
  "did:ixo:entity:abc...xyz",
  ucanToken,
);

const roomId = sourceRoomResponse.roomId;
```

The `ucanToken` carries the caller's capability to act on the entity. The optional `accessToken` is the user's Matrix client-server access token, used only for the local join — never sent to the bot server. See [Matrix authentication](/api-reference/matrix-state-bot-api).

## Upload telemetry into the data room

```ts theme={null}
const matrixApiClient = createMatrixApiClient({
  homeServerUrl: HOME_SERVER_URL,
  accessToken: matrixAccessToken,
});

const upload = await matrixApiClient.media.v1beta1.upload(
  "telemetry-2025-04.json",
  "application/json",
  telemetryFile,
);

const mxcUri = upload.content_uri;
```

## Read or set room state via the State Bot

Use the State Bot to attach structured profile or settings data to an entity room.

```ts theme={null}
const matrixStateBotClient = createMatrixStateBotClient({
  homeServerUrl: HOME_SERVER_URL,
  botUrl: "https://devmx.ixo.earth/bots/state",
  accessToken: matrixAccessToken,
});

const stateData = await matrixStateBotClient.state.v1beta1.queryState(
  roomId,
  "impactsX",
  "profile",
  ucanToken,
);

await matrixStateBotClient.state.v1beta1.setState(
  roomId,
  "impactsX",
  "profile",
  JSON.stringify({ displayName: "Solar Farm Alpha", capacityKw: 5000 }),
  ucanToken,
);
```

<Note>
  Always read state before overwriting. The State Bot does not merge — it replaces the value at the path you set.
</Note>

## Claim flow: submit, evaluate, mint

End-to-end flow for a digital MRV outcome:

```ts theme={null}
const collectionId = "12";
const adminAddress = "ixo1...";
const oracleAddress = "ixo1oracle...";
const tokenContractAddress = "ixo1contract...";

// 1. Submit a claim referencing evidence stored in the data room
const submitClaimMsg = {
  typeUrl: "/ixo.claims.v1beta1.MsgSubmitClaim",
  value: ixo.claims.v1beta1.MsgSubmitClaim.fromPartial({
    creator: signerAddress,
    claimId: "bafkreih...",
    collectionId,
    adminAddress,
  }),
};

await signingClient.signAndBroadcast(signerAddress, [submitClaimMsg], "auto");

// 2. Optional Claim Bot helpers (off-chain co-ordination)
const matrixClaimBotClient = createMatrixClaimBotClient({
  homeServerUrl: HOME_SERVER_URL,
  botUrl: "https://devmx.ixo.earth/bots/claim",
  accessToken: matrixAccessToken,
});

const claimRecord = await matrixClaimBotClient.claim.v1beta1.queryClaim(
  collectionId,
  "bafkreih...",
  ucanToken,
);

// 3. Evaluate after the Agentic Oracle has produced a verification
const evaluateMsg = {
  typeUrl: "/ixo.claims.v1beta1.MsgEvaluateClaim",
  value: ixo.claims.v1beta1.MsgEvaluateClaim.fromPartial({
    creator: signerAddress,
    claimId: "bafkreih...",
    collectionId,
    oracle: oracleAddress,
    adminAddress,
    status: 1, // Approved
    reason: 0,
    verificationProof: "bafkrei-proof-cid",
    amount: [],
  }),
};

await signingClient.signAndBroadcast(signerAddress, [evaluateMsg], "auto");

// 4. Mint outcome tokens against the approved claim
const mintMsg = {
  typeUrl: "/ixo.token.v1beta1.MsgMintToken",
  value: ixo.token.v1beta1.MsgMintToken.fromPartial({
    minter: signerAddress,
    contractAddress: tokenContractAddress,
    owner: recipientAddress,
    mintBatch: [
      ixo.token.v1beta1.MintBatch.fromPartial({
        name: "CARBON",
        index: "bafkreih...",
        amount: "3600",
        collection: "did:ixo:entity:collection456",
        tokenData: [],
      }),
    ],
  }),
};

await signingClient.signAndBroadcast(signerAddress, [mintMsg], "auto");
```

<Note>
  The off-chain oracle call is your application code — see [Agentic Oracles ADK](/sdk-reference/oracle-adk) and [Build agentic oracles](/guides/ixo-oracles-architecture).
</Note>

## Agentic Oracle integration

The off-chain oracle service is built with the [Agentic Oracles ADK](/sdk-reference/oracle-adk) and [Personal Agent ADK](/sdk-reference/oracle-adk). The on-chain side uses `@ixo/impactxclient-sdk` to record `MsgEvaluateClaim`. Wire the two together with whatever HTTP, MCP, or messaging layer your service exposes.

The IXO Oracles ecosystem is private. To request access, see [Build agentic oracles](/guides/ixo-oracles-architecture).

## Next steps

<CardGroup cols={2}>
  <Card title="API reference" icon="book" href="/api-reference/index">
    REST, RPC, GraphQL, and service APIs.
  </Card>

  <Card title="IXO MultiClient SDK" icon="server" href="/sdk-reference/multiclient-sdk">
    Module-level features on protocol.
  </Card>

  <Card title="IXO Matrix Client SDK" icon="cube" href="/sdk-reference/matrix-client-sdk">
    Matrix data rooms and bot clients.
  </Card>

  <Card title="GitHub" icon="github" href="https://github.com/ixofoundation">
    Source code and reference implementations.
  </Card>
</CardGroup>
