# Generating Custom Guard Client for Core Candy Machine

Generate IDL and Initial Client

#### Configuring Shankjs <a href="#configuring-shankjs" id="configuring-shankjs"></a>

Shankjs is a IDL generator that works on both Anchor and non Anchor programs. You want to configure this with your new custom Candy Guard deployment key to properly generate a working client. Edit the file located at `/configs/shank.cjs` in the mpl-candy-machine repo.

```
/configs/shank.cjs

generateIdl({
  generator: "anchor",
  programName: "candy_guard",
  programId: "Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g", // Your custom Candy Guard deployed program key.
  idlDir,
  binaryInstallDir,
  programDir: path.join(programDir, "candy-guard", "program"),
});
```

If you are generating using anchor 28 you will need to add a fallback in to Shankjs idl generator to anchor 27 due to a missing crates.io crate.

```
/configs/shank.cjs

generateIdl({
  generator: "anchor",
  programName: "candy_guard",
  programId: "Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g", // Your custom Candy Guard deployed program key.
  idlDir,
  binaryInstallDir,
  programDir: path.join(programDir, "candy-guard", "program"),
  rustbin: {
    locked: true,
    versionRangeFallback: "0.27.0",
  },
});
```

#### Generate IDL and Client <a href="#generate-idl-and-client" id="generate-idl-and-client"></a>

Now you should be able to generate the IDL and the initial client. From the root of the project run

```
pnpm run generate
```

this will in turn execute both scripts `pnpm generate:idls` and `pnpm generate:clients` and build out the intial clients. If you need to run these seperately for what ever reason you are able to do so.

### Adding Guard(s) to the client <a href="#adding-guard-s-to-the-client" id="adding-guard-s-to-the-client"></a>

#### Create Guard File <a href="#create-guard-file" id="create-guard-file"></a>

Once a sucessful generation of the intial client is made navigate to `/clients/js/src`.

The first step would be to add you new guard into the `/clients/js/src/defaultGuards` folder.

Below is a template you could use and adjust to your needs based on the type of guard you have created. You can name your guard what ever you want but I'm going to name my example `customGuard.ts`

```
import { PublicKey } from '@metaplex-foundation/umi'
import {
  getCustomGuardSerializer,
  CustomGuard,
  CustomGuardArgs,
} from '../generated'
import { GuardManifest, noopParser } from '../guards'

export const customGuardManifest: GuardManifest<
  CustomGuardArgs,
  CustomGuard,
  CustomGuardMintArgs
> = {
  name: 'customGuard',
  serializer: getCustomGuardSerializer,
  mintParser: (context, mintContext, args) => {
    const { publicKeyArg1, arg1 } = args
    return {
      data: new Uint8Array(),
      // Pass in any accounts needed for your custom guard from your mint args.
      // Your guard may or may not need remaining accounts.
      remainingAccounts: [
        { publicKey: publicKeyArg1, isWritable: true },
        { publicKey: publicKeyArg2, isWritable: false },
      ],
    }
  },
  routeParser: noopParser,
}

// Here you would fill out any custom Mint args needed for your guard to operate.
// Your guard may or may not need MintArgs.

export type CustomGuardMintArgs = {
  /**
   * Custom Guard Mint Arg 1
   */
  publicKeyArg1: PublicKey

  /**
   * Custom Guard Mint Arg 2
   */
  publicKeyArg2: PublicKey

  /**
   * Custom Guard Mint Arg 3.
   */
  arg3: Number
}
```

#### Add Guard to Existing Files <a href="#add-guard-to-existing-files" id="add-guard-to-existing-files"></a>

From here you need to add your new guard to some existing files.

Export your new guard from `/clients/js/src/defaultGuards.index.ts`

```
...
export * from './tokenGate';
export * from './tokenPayment';
export * from './token2022Payment';
// add your guard to the list
export * from './customGuard';
```

Within `/clients/js/src/defaultGuards.defaults.ts` add your guard to these locations;

```
import { CustomGuardArgs } from "../generated"

export type DefaultGuardSetArgs = GuardSetArgs & {
    ...
     // add your guard to the list
    customGuard: OptionOrNullable<CustomGuardArgs>;
}
```

```
import { customGuard } from "../generated"

export type DefaultGuardSet = GuardSet & {
    ...
     // add your guard to the list
    customGuard: Option<CustomGuard>
}
```

```
import { CustomGuardMintArgs } from "./defaultGuards/customGuard.ts"
export type DefaultGuardSetMintArgs = GuardSetMintArgs & {
    ...
    // add your guard to the list
    customGuard: OptionOrNullable<CustomGuardMintArgs>
}
```

```
export const defaultCandyGuardNames: string[] = [
  ...// add your guard to the list
  'customGuard',
]
```

Finally you need to add the exported customGuardManifest to the plugin file located at `/clients/js/src/plugin.ts`

```
import {customGuardManifest} from "./defaultGuards"

umi.guards.add(
  ...// add your guard manifest to the list
  customGuardManifest
)
```

From this point you can build and upload your client package to npm or link/move it to your project folder where you would like to access the new guard client.

It is worth using the built in testing suite of AVA to write some tests that fully test your guard in multiple scenarios. Examples of tests can be found in `/clients/js/tests`.


---

# Agent Instructions: 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:

```
GET https://8bit-1.gitbook.io/solibrary/generating-custom-guard-client-for-core-candy-machine.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
