> For the complete documentation index, see [llms.txt](https://docs.seismic.systems/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.seismic.systems/tutorials/understanding-the-clown-beatdown-contract/building-the-cli/chapter-1-constants-and-utilities.md).

# Ch 1: Constants and Utilities

In this chapter, you will learn about defining constants and utility functions which we will frequently use throughout the project. *Estimated time: \~10 minutes*

First, navigate to the root of the directory/monorepo and run `bun install` to install all the dependencies.

Now, navigate to make a `lib` folder inside `packages/cli` with the files `constants.ts` and `utils.ts` and navigate to it:

```
mkdir -p packages/cli/lib
touch packages/cli/lib/constants.ts packages/cli/lib/utils.ts
cd packages/cli/lib
```

`constants.ts` will contain the constants we use throughout the project while `utils.ts` will contain the necessary utility functions.

Add the following to `constants.ts`:

```typescript
import { join } from "path";

const CONTRACT_NAME = "ClownBeatdown";
const CONTRACT_DIR = join(__dirname, "../../contracts");

export { CONTRACT_NAME, CONTRACT_DIR };
```

This file centralizes key project constants:

* `CONTRACT_NAME`: The ClownBeatdown contract name.
* `CONTRACT_DIR`: Path to the contracts directory.

Now, add the following to `utils.ts`:

```typescript
import fs from "fs";
import { type ShieldedWalletClient, getShieldedContract } from "seismic-viem";
import { Abi, Address } from "viem";

async function getShieldedContractWithCheck(
  walletClient: ShieldedWalletClient,
  abi: Abi,
  address: Address,
) {
  const contract = getShieldedContract({
    abi: abi,
    address: address,
    client: walletClient,
  });

  const code = await walletClient.getCode({
    address: address,
  });
  if (!code) {
    throw new Error("Please deploy contract before running this script.");
  }

  return contract;
}

function readContractAddress(broadcastFile: string): `0x${string}` {
  const broadcast = JSON.parse(fs.readFileSync(broadcastFile, "utf8"));
  if (!broadcast.transactions?.[0]?.contractAddress) {
    throw new Error("Invalid broadcast file format");
  }
  return broadcast.transactions[0].contractAddress;
}

function readContractABI(abiFile: string): Abi {
  const abi = JSON.parse(fs.readFileSync(abiFile, "utf8"));
  if (!abi.abi) {
    throw new Error("Invalid ABI file format");
  }
  return abi.abi;
}

export { getShieldedContractWithCheck, readContractAddress, readContractABI };
```

This file contains utility functions to interact with your ClownBeatdown contract:

* `getShieldedContractWithCheck`: Ensures the contract is deployed and returns a shielded contract instance.
* `readContractAddress`: Reads the deployed contract's address from a broadcast file.
* `readContractABI`: Parses the contract's ABI from an ABI file for use in interactions.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.seismic.systems/tutorials/understanding-the-clown-beatdown-contract/building-the-cli/chapter-1-constants-and-utilities.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
