Nym Smart Contract Clients
To query or execute on any of the Nym contracts, use the Contract Clients (opens in a new tab), which contain read-only query and signing clients for all of Nym's smart contracts.
Contract Clients
| Client | Functionality | Methods |
|---|---|---|
| Coconut Bandwidth | Manages depositing and release of funds. Tracks double spending. | Source (opens in a new tab) |
| Coconut DKG | Allows signers to derive keys for issuing Coconut credentials. | Source (opens in a new tab) |
| Cw3FlexMultisig | Used by the Coconut APIs to issue credentials. cw3-flex-multisig (opens in a new tab) backed by cw4. | Source (opens in a new tab) |
| Cw4Group | Used by the Coconut APIs. Cw4 Group (opens in a new tab) stores members with an admin. | Source (opens in a new tab) |
| Mixnet | Manages the network topology, tracking delegations and rewards. | Source (opens in a new tab) |
| Name Service | Directory of user-defined aliases, analogous to DNS. | Source (opens in a new tab) |
| Service Provider Directory | Public directory for registering service providers. | Source (opens in a new tab) |
| Vesting | Manages NYM token vesting functionality. | Source (opens in a new tab) |
Environment Setup
Create a new project with Vite:
npm create vite@latestChoose React + TypeScript, then:
cd <YOUR_APP>
npm i
npm run devQuery Example
Installation
npm install @nymproject/contract-clients @cosmjs/cosmwasm-stargateQuerying the Mixnet Contract
This example uses MixnetQueryClient to fetch a paged list of mixnodes from the contract. Create a settings.ts file for your network configuration:
settings.ts
export const settings = {
url: "wss://rpc.nymtech.net:443",
mixnetContractAddress: "n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr",
};App.tsx
import { useEffect, useState } from "react";
import { contracts } from "@nymproject/contract-clients";
import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { settings } from "./settings";
import Box from "@mui/material/Box";
import CircularProgress from "@mui/material/CircularProgress";
const getClient = async () => {
const cosmWasmClient = await SigningCosmWasmClient.connect(settings.url);
const client = new contracts.Mixnet.MixnetQueryClient(
cosmWasmClient,
settings.mixnetContractAddress
);
return client;
};
export const Mixnodes = () => {
const [mixnodes, setMixnodes] = useState<any>();
const getMixnodes = async () => {
const client = await getClient();
const { nodes } = await client.getMixNodesDetailed({});
setMixnodes(nodes);
};
useEffect(() => {
getMixnodes();
}, []);
if (!mixnodes) {
return (
<Box sx={{ display: "flex" }}>
<CircularProgress />
</Box>
);
}
return (
<div style={{ marginTop: "1rem" }}>
{mixnodes?.length &&
mixnodes.map((mixnode: any) => (
<Box className="codeBox" key={mixnode.bond_information.mix_id}>
<span style={{ marginRight: "1rem" }}>
{`id: ${mixnode.bond_information.mix_id}`}
</span>
<span>{`owner: ${mixnode.bond_information.owner}`}</span>
</Box>
))}
</div>
);
};Execute Example
Installation
npm install @nymproject/contract-clients @cosmjs/cosmwasm-stargate @cosmjs/proto-signingExecuting Contract Methods
This example uses MixnetClient with a signer to execute methods like delegation.
Update your settings.ts to include signing credentials:
settings.ts
export const settings = {
url: "wss://rpc.nymtech.net:443",
mixnetContractAddress: "<ENTER MIXNET CONTRACT ADDRESS>",
mnemonic: "<ENTER MNEMONIC>",
address: "<ENTER NYM ADDRESS>",
};App.tsx
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() {
signer = await DirectSecp256k1HdWallet.fromMnemonic(settings.mnemonic, {
prefix: "n",
});
const cosmWasmClient = await SigningCosmWasmClient.connectWithSigner(
settings.url,
signer,
{ gasPrice: GasPrice.fromString("0.025unym") }
);
cosmWasmSigningClient = cosmWasmClient;
const mixnetClient = new contracts.Mixnet.MixnetClient(
cosmWasmSigningClient,
settings.address,
settings.mixnetContractAddress
);
signerMixnetClient = mixnetClient;
}
const getDelegations = async () => {
if (!signerMixnetClient) return;
delegations = await signerMixnetClient.getDelegatorDelegations({
delegator: settings.address,
});
};
const doDelegation = async () => {
if (!signerMixnetClient) return;
const res = await signerMixnetClient.delegateToMixnode(
{ mixId },
"auto",
undefined,
[{ amount: `${amountToDelegate}`, denom: "unym" }]
);
console.log(res);
};
const doUndelegateAll = async () => {
for (const delegation of delegations.delegations) {
await signerMixnetClient.undelegateFromMixnode(
{ mixId: delegation.mix_id },
"auto"
);
}
};
const doSendTokens = async () => {
const res = await cosmWasmSigningClient.sendTokens(
settings.address,
nodeAddress,
[{ amount: amountToSend, denom: "unym" }],
"auto",
"test sending tokens"
);
console.log(res);
};
ExecuteOnNyx();
setTimeout(() => getDelegations(), 1000);
return (
<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)} />
<button onClick={() => doSendTokens()}>Send Tokens</button>
<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)} />
<button onClick={() => doDelegation()}>Delegate</button>
<button onClick={() => doUndelegateAll()}>Undelegate All</button>
</div>
);
}