import { Callout } from 'nextra/components'

# Nym Smart Contract Clients
<Callout type="error">
    The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.

    When the issue is resolved, this will be reflected in the documentation.

    Thanks for your patience!
</Callout>
As previously mentioned, to query or execute on any of the Nym contracts, you'll need to use one of the [`Contract Clients`](https://www.npmjs.com/package/@nymproject/contract-clients), which contains read-only query and signing clients for all of Nym's smart contracts.

##### Contract Clients list
Lists of the different available clients and methods from the `Contract Clients` can be found in the `.client.ts` files:
| Client name             | Functionality| Methods list |
| :-------------:         | :----------: | :----------: |
| Coconut Bandwidth Client| Manages the depositing and release of funds. Tracks double spending.             | [Coconut Bandwidth](https://github.com/nymtech/nym/blob/develop/sdk/typescript/codegen/contract-clients/src/CoconutBandwidth.client.ts) |
| Coconut DKG Client      | Allows signers participating in issuing Coconut credentials to derive keys to be used.             | [Coconut DKG](https://github.com/nymtech/nym/blob/develop/sdk/typescript/codegen/contract-clients/src/CoconutDkg.client.ts) |
| Cw3FlexMultisig Client  | Used by the Coconut APIs to issue credentials. [This](https://github.com/CosmWasm/cw-plus/tree/main/contracts/cw3-flex-multisig) is a multisig contract that is backed by the cw4 (group) contract, which independently maintains the voter set.             | [Cw3Flex Multisig](https://github.com/nymtech/nym/blob/develop/sdk/typescript/codegen/contract-clients/src/Cw3FlexMultisig.client.ts) |
| Cw4Group Client         | Used by the Coconut APIs to issue credentials. [Cw4 Group](https://github.com/CosmWasm/cw-plus/tree/main/contracts/cw4-group) stores a set of members along with an admin, and allows the admin to update the state.              | [Cw4Group](https://github.com/nymtech/nym/blob/develop/sdk/typescript/codegen/contract-clients/src/Cw4Group.client.ts) |
| Mixnet Client           | Manages the network topology of the mixnet, tracking delegations and rewards.           | [Mixnet](https://github.com/nymtech/nym/blob/develop/sdk/typescript/codegen/contract-clients/src/Mixnet.client.ts) |
| Name Service Client     | Operates as a directory of user-defined aliases, analogous to a Domain Name System (DNS).              | [Name service](https://github.com/nymtech/nym/blob/develop/sdk/typescript/codegen/contract-clients/src/NameService.client.ts) |
| Service provider Directory Client| Allows users to register their service provider in a public directory.      | [Service Provider](https://github.com/nymtech/nym/blob/develop/sdk/typescript/codegen/contract-clients/src/ServiceProviderDirectory.client.ts) |
| Vesting Client          |     Manages NYM token vesting functionality.         | [Vesting](https://github.com/nymtech/nym/blob/develop/sdk/typescript/codegen/contract-clients/src/Vesting.client.ts) |



##### Environment Setup
Begin by creating a directory and configuring your application environment:

```bash
npm create vite@latest
```

During the environment setup, choose React and subsequently opt for Typescript if you want your application to function smoothly following this tutorial. Next, navigate to your application directory and run the following commands:
```bash
cd < YOUR_APP >
npm i
npm run dev
```

##### Installation
Install the packages and their dependencies if you don't already have them:
```bash
npm install @nymproject/contract-clients @cosmjs/cosmwasm-stargate
```

## Query clients

In the `src` folder, open the `App.tsx` file and delete all the code.

##### Imports
Import the contracts' client in your app:
````js
import { contracts } from '@nymproject/contract-clients';
import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
````

##### Example: using the mixnet smart contract client to query
In this example, we will use the `MixnetQueryClient`from the `Contract Clients` to simply query the contract and return a list of mixnodes.

```ts
import "./App.css";
import { contracts } from "@nymproject/contract-clients";
import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { useEffect, useState } from "react";

export default function Mixnodes() {

  const [mixnodes, setMixnodes] = useState<any>([]);

  async function fetchMixnodes(){
    // Set-up the CosmWasm Client
    const cosmWasmClient = await SigningCosmWasmClient.connect("wss://rpc.nymtech.net:443");
    const client = new contracts.Mixnet.MixnetQueryClient(
      cosmWasmClient,
      "n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr" // The mainnet mixnet contract address (which will be different on mainnet, QA, etc)
    );
    const result = await client.getMixNodesDetailed({});
    setMixnodes(result.nodes)
  }

  useEffect(() => {
    fetchMixnodes();
  }, [])

  return(
    <>
      <table>
        <tbody>
          {mixnodes?.map((value: any, index: number) => {
            return(
              <tr key={index}>
                <td> {value?.bond_information?.mix_node?.identity_key} </td>
              </tr>
            )
          })
          }
        </tbody>
      </table>
    </>
  )
}
```

By pasting the above code in the `App.tsx` file and `npm run dev` your app from the terminal, you should see an unstyled printed list of Nym mixnodes!




## Execute clients

##### Installation
Install the packages and their dependencies if you don't already have them:

```bash
npm install @nymproject/contract-clients @cosmjs/cosmwasm-stargate @cosmjs/proto-signing
```


##### Imports
Import the contracts' execute clients in your app:
````js
import { contracts } from '@nymproject/contract-clients';
import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
````

##### Example: using the Mixnet smart contract client to execute methods
In this example, we will use the `MixnetClient`and the `signer` from the [`Contract Clients`](https://www.npmjs.com/package/@nymproject/contract-clients) to execute methods.

Note that you will need to create a `settings.ts` file (here created in the same directory), using the following structure:
```json

export const mySettings = {
    url: "wss://rpc.nymtech.net:443",
    mixnetContractAddress: '<ENTER MIXNET CONTACT ADDRESS HERE>',
    mnemonic: '<ENTER MNEMONIC HERE>',
    address: '<ENTER NYM ADDRESS HERE>'
};

export const settings = mySettings;
```

```ts
import "./App.css";
import { contracts } from "@nymproject/contract-clients";
import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import { GasPrice } from "@cosmjs/stargate";
import { settings } from "./settings";

export default function Exec() {
  let signer: DirectSecp256k1HdWallet;
  let signerMixnetClient: any;
  let cosmWasmSigningClient: SigningCosmWasmClient;
  let mixId: number;
  let amountToDelegate: string;
  let nodeAddress: string;
  let amountToSend: string;
  let delegations: any;

  async function ExecuteOnNyx() {
    // Cosmos client
    signer = await DirectSecp256k1HdWallet.fromMnemonic(settings.mnemonic, {
      prefix: "n",
    });
    const cosmWasmClient = await SigningCosmWasmClient.connectWithSigner(
      settings.url,
      signer,
      {
        gasPrice: GasPrice.fromString("0.025unym"),
      }
    );
    // Save globally
    cosmWasmSigningClient = cosmWasmClient;

    // Nym client
    const mixnetClient = new contracts.Mixnet.MixnetClient(
      cosmWasmSigningClient,
      settings.address, // Sender (that account of the signer)
      settings.mixnetContractAddress // Contract address (different on mainnet, QA, etc)
    );
    // Save globally
    signerMixnetClient = mixnetClient;

  }

  // Get delegations
  const getDelegations = async () => {
    if (!signerMixnetClient) {
      return;
    }
    const delegationsObject = await signerMixnetClient.getDelegatorDelegations({
      delegator: settings.address,
    });
    delegations = delegationsObject;
  };

  // Make delegation
  const doDelegation = async () => {
    if (!signerMixnetClient) {
      return;
    }
    const res = await signerMixnetClient.delegateToMixnode(
      { mixId },
      "auto",
      undefined,
      [{ amount: `${amountToDelegate}`, denom: "unym" }]
    );
    console.log(res);
  };

  // Undelegate all
  const doUndelegateAll = async () => {
    for (const delegation of delegations.delegations) {
      await signerMixnetClient.undelegateFromMixnode(
        { mixId: delegation.mix_id },
        "auto"
      );
    }
  };

  // Sending tokens
  const doSendTokens = async () => {
    const memo = "test sending tokens";
    const res = await cosmWasmSigningClient.sendTokens(
      settings.address,
      nodeAddress,
      [{ amount: amountToSend, denom: "unym" }],
      "auto",
      memo
    );
    console.log(res);
  };

  ExecuteOnNyx();
  setTimeout(() => getDelegations(), 1000);

  return (
    <div>
      <p>Exec</p>
      <div>
        <p>Send Tokens</p>
        <input
          type="string"
          placeholder="Node Address"
          onChange={(e) => (nodeAddress = e.target.value)}
        />
        <input
          type="number"
          placeholder="Amount"
          onChange={(e) => (amountToSend = e.target.value)}
        />
        <div>
          <button onClick={() => doSendTokens()}>Send Tokens</button>
        </div>
      </div>
      <div>
        <p>Delegate</p>
        <input
          type="number"
          placeholder="Mixnode Id"
          onChange={(e) => (mixId = +e.target.value)}
        />
        <input
          type="number"
          placeholder="Amount"
          onChange={(e) => (amountToDelegate = e.target.value)}
        />
        <div>
          <button onClick={() => doDelegation()}>Delegate</button>
        </div>
        <div>
          <button onClick={() => doUndelegateAll()}>Undelegate All</button>
        </div>
      </div>
    </div>
  );
}
```
