Add modules
When a new module is added to Terra Core, you must also add it to several places in feather.js. To add a module, 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
- 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 a 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
_37import { JSONSerializable } from '../../../util/json';_37import { AccAddress } from '../../strings';_37_37/**_37 * Just a simple greeting on the blockchain._37 */_37export class MsgHello extends JSONSerializable<MsgHello.Data> {_37  constructor(public recipient: AccAddress) {_37    super();_37  }_37_37  public static fromData(data: MsgHello.Data): MsgHello {_37    const {_37      value: { recipient },_37    } = data;_37    return new MsgHello(recipient);_37  }_37_37  public toData(): MsgHello.Data {_37    const { recipient } = this;_37    return {_37      type: 'greeting/MsgHello',_37      value: {_37        recipient,_37      },_37    };_37  }_37}_37_37export namespace MsgHello {_37  export interface Data {_37    type: 'greeting/MsgHello';_37    value: {_37      recipient: AccAddress;_37    };_37  }_37}
- Create the following file, which will index your new messages.
 
src/core/greeting/msgs/index.ts
_11import { MsgHello } from './MsgHello';_11import { MsgGoodbye } from './MsgGoodbye';_11_11export * from './MsgHello';_11export * from './MsgGoodbye';_11_11export type GreetingMsg = MsgHello | MsgGoodbye;_11_11export namespace GreetingMsg {_11  export type Data = MsgHello.Data | MsgGoodbye.Data;_11}
- Register the messages in 
src/core/Msg.tsso that they can be parsed correctly. 
src/core/Msg.ts
_46// import greeting module messages_46..._46import {_46  MsgHello,_46  MsgGoodbye,_46  GreetingMsg_46} from './greeting/msgs';_46..._46_46// register GreetingMsg_46export type Msg =_46  | BankMsg_46  | DistributionMsg_46  | GovMsg_46  | GreetingMsg // ADD HERE_46  | MsgAuthMsg_46  | SlashingMsg_46  | StakingMsg_46  | WasmMsg;_46_46..._46_46// register GreetingMsg.Data_46export namespace Msg {_46  export type Data =_46    | BankMsg.Data_46    | DistributionMsg.Data_46    | GovMsg.Data_46    | Greeting.Data // ADD HERE_46    | MsgAuthMsg.Data_46    | SlashingMsg.Data_46    | StakingMsg.Data_46    | WasmMsg.Data;_46..._46_46  // register deserializer in Msg.fromData(...)_46  export function fromData(data: Msg.Data): Msg {_46  ..._46      // greeting_46      case 'greeting/MsgHello':_46        return MsgHello.fromData(data);_46      case 'greeting/MsgGoodbye':_46        return MsgGoodbye.fromData(data);_46  ..._46  }_46}
- Register the messages to be exported in 
src/core/index.ts: 
_3..._3// greeting_3export 'greeting/msgs';
- Add parameter changes.
 
feather.js provides an easy way to generate ParameterChangeProposals, 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
_30import { ParamChange } from '..';_30import { Convert } from '../../util/convert';_30_30type MaxHellos = ParamChange.Type<'greeting', 'maxhellos', number>;_30_30type MaxGoodbyes = ParamChange.Type<'greeting', 'maxgoodbyes', number>;_30_30export type GreetingParamChange = MaxHellos | MaxGoodbyes;_30_30export namespace GreetingParamChange {_30  export type Data =_30    | ParamChange.Data.Type<MaxHellos>_30    | ParamChange.Data.Type<MaxGoodbyes>;_30}_30_30export interface GreetingParamChanges {_30  greeting?: {_30    maxhellos?: number;_30    maxgoodbyes?: number;_30  };_30}_30_30export namespace GreetingParamChanges {_30  export const ConversionTable = {_30    greeting: {_30      maxhellos: [Convert.toNumber, Convert.toFixed],_30      maxgoodbyes: [Convert.toNumber, Convert.toFixed],_30    },_30  };_30}
- Register parameter change types
 
src/core/params/ParamChange.ts
_32..._32import { GreetingParamChange, GreetingParamChanges } from '../greeting/params';_32..._32_32export type ParamChanges = DistributionParamChanges &_32  GovParamChanges &_32  GreetingParamChanges & // ADD HERE_32  SlashingParamChanges &_32  StakingParamChanges &_32  WasmParamChanges;_32_32export namespace ParamChanges {_32  export const ConversionTable = {_32    ...DistributionParamChanges.ConversionTable,_32    ...GovParamChanges.ConversionTable,_32    ...GreetingParamChanges.ConverstionTable, // ADD HERE_32    ...SlashingParamChanges.ConversionTable,_32    ...StakingParamChanges.ConversionTable,_32    ...WasmParamChanges.ConversionTable,_32  };_32_32..._32_32export type ParamChange =_32  | DistributionParamChange_32  | GovParamChange_32  | GreetingParamChange // ADD HERE_32  | SlashingParamChange_32  | StakingParamChange_32  | WasmParamChange;_32_32...
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
- Create 
src/client/lcd/api/GreetingAPI.tswith the following: 
_32import { BaseAPI } from './BaseAPI';_32import { AccAddress } from '../../../core/strings';_32_32export interface GreetingParams {_32  max_hellos: number;_32  max_goodbyes: number;_32}_32_32export namespace GreetingParams {_32  export interface Data {_32    max_hellos: string;_32    max_goodbyes: string;_32  }_32}_32_32export class GreetingAPI extends BaseAPI {_32  public async hello(accAddress: AccAddress): Promise<AccAddress[]> {_32    return this.c_32      .get<AccAddress[]>(`/greeting/hello/${accAddress}`)_32      .then((d) => d.result);_32  }_32_32  public async parameters(): Promise<GreetingParams> {_32    return this.c_32      .get<GreetingParams.Data>(`/greeting/parameters`)_32      .then((d) => d.result)_32      .then((d) => ({_32        max_hellos: Number.parseInt(d.max_hellos),_32        max_goodbyes: Number.parseInt(d.max_goodbyes),_32      }));_32  }_32}
- Register the API functionality inside 
src/client/lcd/api/index.ts: 
_12export * from './AuthAPI';_12export * from './BankAPI';_12export * from './DistributionAPI';_12export * from './GovAPI';_12export * from './GreetingAPI'; // ADD HERE_12export * from './MsgAuthAPI';_12export * from './SlashingAPI';_12export * from './StakingAPI';_12export * from './SupplyAPI';_12export * from './TendermintAPI';_12export * from './TxAPI';_12export * from './WasmAPI';
- Add the functionality to 
src/client/lcd/LCDClient.ts: 
_63..._63import {_63  AuthAPI,_63  BankAPI,_63  DistributionAPI,_63  GovAPI,_63  GreetingAPI, // ADD HERE_63  MsgAuthAPI,_63  SlashingAPI,_63  StakingAPI,_63  SupplyAPI,_63  TendermintAPI,_63  TxAPI,_63  WasmAPI,_63} from './api';_63..._63_63_63export class LCDClient {_63  public config: LCDClientConfig;_63  public apiRequester: APIRequester;_63_63  // API access_63  public auth: AuthAPI;_63  public bank: BankAPI;_63  public distribution: DistributionAPI;_63  public gov: GovAPI;_63  public greeting: GreetingAPI; // ADD HERE_63  public msgauth: MsgAuthAPI;_63  public slashing: SlashingAPI;_63  public staking: StakingAPI;_63  public supply: SupplyAPI;_63  public tendermint: TendermintAPI;_63  public wasm: WasmAPI;_63  public tx: TxAPI;_63_63  /**_63   * Creates a new LCD client with the specified configuration._63   *_63   * @param config LCD configuration_63   */_63  constructor(config: LCDClientConfig) {_63    this.config = {_63      ...DEFAULT_LCD_OPTIONS,_63      ...config,_63    };_63_63    this.apiRequester = new APIRequester(this.config.URL);_63_63    // instantiate APIs_63    this.auth = new AuthAPI(this.apiRequester);_63    this.bank = new BankAPI(this.apiRequester);_63    this.distribution = new DistributionAPI(this.apiRequester);_63    this.gov = new GovAPI(this.apiRequester);_63    this.greeting = new GreetingAPI(this.apiRequester); // ADD HERE_63    this.msgauth = new MsgAuthAPI(this.apiRequester);_63    this.slashing = new SlashingAPI(this.apiRequester);_63    this.staking = new StakingAPI(this.apiRequester);_63    this.supply = new SupplyAPI(this.apiRequester);_63    this.tendermint = new TendermintAPI(this.apiRequester);_63    this.wasm = new WasmAPI(this.apiRequester);_63    this.tx = new TxAPI(this);_63  }