# Add modules

When a new module is added to Paloma, you must add it to several places in Paloma.js too. To add it, complete the following steps:

## Create a new folder

In the `src/core` folder, create a new folder and name it after the new module. For example, `src/core/greeting`.

## Add messages

1. Register new messages in a subdirectory in the folder that you created for your new module, as shown in the following example:

`src/core/greeting/msgs`

For this example, let's assume that you are creating two new messages, `MsgHello` and `MsgGoodbye`. The following example shows the code for `MsgHello`, and you can extrapolate from it the way to implement `MsgGoodbye`.

`src/core/greeting/msgs/MsgHello.ts`

```ts
   import { JSONSerializable } from "../../../util/json";
   import { AccAddress } from "../../strings";

/**
    * Just a simple greeting on the blockchain.
    */
   export class MsgHello extends JSONSerializable<MsgHello.Data> {
     constructor(public recipient: AccAddress) {
       super();
     }

public static fromData(data: MsgHello.Data): MsgHello {
       const {
         value: { recipient },
       } = data;
       return new MsgHello(recipient);
     }

public toData(): MsgHello.Data {
       const { recipient } = this;
       return {
         type: "greeting/MsgHello",
         value: {
           recipient,
         },
       };
     }
   }

export namespace MsgHello {
     export interface Data {
       type: "greeting/MsgHello";
       value: {
         recipient: AccAddress;
       };
     }
   }
   ```

2. Create the following file, which will index your new messages.

`src/core/greeting/msgs/index.ts`

```ts
   import { MsgHello } from "./MsgHello";
   import { MsgGoodbye } from "./MsgGoodbye";

export * from "./MsgHello";
   export * from "./MsgGoodbye";

export type GreetingMsg = MsgHello | MsgGoodbye;

export namespace GreetingMsg {
     export type Data = MsgHello.Data | MsgGoodbye.Data;
   }
   ```

3. Register the messages in `src/core/Msg.ts` so that they can be parsed correctly.

`src/core/Msg.ts`

```ts
   // import greeting module messages
   ...
   import {
     MsgHello,
     MsgGoodbye,
     GreetingMsg
   } from './greeting/msgs';
   ...

// register GreetingMsg
   export type Msg =
     | BankMsg
     | DistributionMsg
     | GovMsg
     | GreetingMsg // ADD HERE
     | MsgAuthMsg
     | SlashingMsg
     | StakingMsg
     | WasmMsg;
   ...

// register GreetingMsg.Data
   export namespace Msg {
     export type Data =
       | BankMsg.Data
       | DistributionMsg.Data
       | GovMsg.Data
       | Greeting.Data // ADD HERE
       | MsgAuthMsg.Data
       | SlashingMsg.Data
       | StakingMsg.Data
       | WasmMsg.Data;
   ...

// register deserializer in Msg.fromData(...)
     export function fromData(data: Msg.Data): Msg {
     ...
         // greeting
         case 'greeting/MsgHello':
           return MsgHello.fromData(data);
         case 'greeting/MsgGoodbye':
           return MsgGoodbye.fromData(data);
     ...
     }
   }
   ```

4. Register the messages to be exported in `src/core/index.ts`:

```ts
   ...
   // greeting
   export 'greeting/msgs';
   ```

5. Add parameter changes.

Paloma.js provides an easy way to generate `ParameterChangeProposal`s, which is a proposal for changing the blockchain parameters associated with a module. If your module has parameters that can be changed via proposal, you should create the following files:

`src/core/greeting/params.ts`

```ts
   import { ParamChange } from "..";
   import { Convert } from "../../util/convert";

type MaxHellos = ParamChange.Type<"greeting", "maxhellos", number>;

type MaxGoodbyes = ParamChange.Type<"greeting", "maxgoodbyes", number>;

export type GreetingParamChange = MaxHellos | MaxGoodbyes;

export namespace GreetingParamChange {
     export type Data =
       | ParamChange.Data.Type<MaxHellos>
       | ParamChange.Data.Type<MaxGoodbyes>;
   }

export interface GreetingParamChanges {
     greeting?: {
       maxhellos?: number;
       maxgoodbyes?: number;
     };
   }

export namespace GreetingParamChanges {
     export const ConversionTable = {
       greeting: {
         maxhellos: [Convert.toNumber, Convert.toFixed],
         maxgoodbyes: [Convert.toNumber, Convert.toFixed],
       },
     };
   }
   ```

6. Register parameter change types

`src/core/params/ParamChange.ts`

```ts
   ...
   import { GreetingParamChange, GreetingParamChanges } from '../greeting/params';
   ...

export type ParamChanges = DistributionParamChanges &
     GovParamChanges &
     GreetingParamChanges & // ADD HERE
     SlashingParamChanges &
     StakingParamChanges &
     WasmParamChanges;

export namespace ParamChanges {
     export const ConversionTable = {
       ...DistributionParamChanges.ConversionTable,
       ...GovParamChanges.ConversionTable,
       ...GreetingParamChanges.ConverstionTable, // ADD HERE
       ...SlashingParamChanges.ConversionTable,
       ...StakingParamChanges.ConversionTable,
       ...WasmParamChanges.ConversionTable,
     };
   ...

export type ParamChange =
     | DistributionParamChange
     | GovParamChange
     | GreetingParamChange // ADD HERE
     | SlashingParamChange
     | StakingParamChange
     | WasmParamChange;
   ...
   ```

## Add API functionality to the LCDClient

If there are API endpoints that exist for the new module, you will need to add this functionality to `LCDClient` so that they are accessible.

Assume that the `greeting` module has the following endpoints:

- `GET /greeting/hello/{accAddress}`
- `GET /greeting/parameters`

1. Create `src/client/lcd/api/GreetingAPI.ts` with the following:

```ts
   import { BaseAPI } from "./BaseAPI";
   import { AccAddress } from "../../../core/strings";

export interface GreetingParams {
     max_hellos: number;
     max_goodbyes: number;
   }

export namespace GreetingParams {
     export interface Data {
       max_hellos: string;
       max_goodbyes: string;
     }
   }

export class GreetingAPI extends BaseAPI {
     public async hello(accAddress: AccAddress): Promise<AccAddress[]> {
       return this.c
         .get<AccAddress[]>(`/greeting/hello/${accAddress}`)
         .then((d) => d.result);
     }

public async parameters(): Promise<GreetingParams> {
       return this.c
         .get<GreetingParams.Data>(`/greeting/parameters`)
         .then((d) => d.result)
         .then((d) => ({
           max_hellos: Number.parseInt(d.max_hellos),
           max_goodbyes: Number.parseInt(d.max_goodbyes),
         }));
     }
   }
   ```

2. Register the API functionality inside `src/client/lcd/api/index.ts`:

```ts
   export * from "./AuthAPI";
   export * from "./BankAPI";
   export * from "./DistributionAPI";
   export * from "./GovAPI";
   export * from "./GreetingAPI"; // ADD HERE
   export * from "./MsgAuthAPI";
   export * from "./SlashingAPI";
   export * from "./StakingAPI";
   export * from "./SupplyAPI";
   export * from "./TendermintAPI";
   export * from "./TxAPI";
   export * from "./WasmAPI";
   ```

3. Add the functionality to `src/client/lcd/LCDClient.ts`:

```ts
   ...
   import {
     AuthAPI,
     BankAPI,
     DistributionAPI,
     GovAPI,
     GreetingAPI, // ADD HERE
     MsgAuthAPI,
     SlashingAPI,
     StakingAPI,
     SupplyAPI,
     TendermintAPI,
     TxAPI,
     WasmAPI,
   } from './api';
   ...

export class LCDClient {
     public config: LCDClientConfig;
     public apiRequester: APIRequester;

// API access
     public auth: AuthAPI;
     public bank: BankAPI;
     public distribution: DistributionAPI;
     public gov: GovAPI;
     public greeting: GreetingAPI; // ADD HERE
     public msgauth: MsgAuthAPI;
     public slashing: SlashingAPI;
     public staking: StakingAPI;
     public supply: SupplyAPI;
     public tendermint: TendermintAPI;
     public wasm: WasmAPI;
     public tx: TxAPI;

/**
      * Creates a new LCD client with the specified configuration.
      *
      * @param config LCD configuration
      */
     constructor(config: LCDClientConfig) {
       this.config = {
         ...DEFAULT_LCD_OPTIONS,
         ...config,
       };

this.apiRequester = new APIRequester(this.config.URL);

// instantiate APIs
       this.auth = new AuthAPI(this.apiRequester);
       this.bank = new BankAPI(this.apiRequester);
       this.distribution = new DistributionAPI(this.apiRequester);
       this.gov = new GovAPI(this.apiRequester);
       this.greeting = new GreetingAPI(this.apiRequester); // ADD HERE
       this.msgauth = new MsgAuthAPI(this.apiRequester);
       this.slashing = new SlashingAPI(this.apiRequester);
       this.staking = new StakingAPI(this.apiRequester);
       this.supply = new SupplyAPI(this.apiRequester);
       this.tendermint = new TendermintAPI(this.apiRequester);
       this.wasm = new WasmAPI(this.apiRequester);
       this.tx = new TxAPI(this);
     }
   }
   ```
