# TS Codegen Documentation
Ts Codegen
import { DownloadButton } from '../../components/download-button';
# @cosmwasm/ts-codegen
Generate TypeScript SDKs for your CosmWasm smart contracts
```
npm install -g @cosmwasm/ts-codegen
```
The quickest and easiest way to interact with CosmWasm Contracts. `@cosmwasm/ts-codegen` converts your CosmWasm smart contracts into dev-friendly TypeScript classes so you can focus on shipping code.
🎥 [Checkout our video playlist](https://www.youtube.com/watch?v=D_A5V2PfNLA&list=PL-lMkVv7GZwz1KO3jANwr5W4MoziruXwK) to learn how to use `ts-codegen`!
## Table of contents
- [@cosmwasm/ts-codegen](https://www.npmjs.com/package/@cosmwasm/ts-codegen)
- [Table of contents](#table-of-contents)
- [QuickStart](#quickstart)
- [Usage](#usage)
- [Programmatic Usage](#programmatic-usage)
- [Types](#types)
- [TS Clients](#client)
- [React Query](#react-query)
- [Recoil](#recoil)
- [Message Composer](#message-composer)
- [Message Builder](#message-builder)
- [Use Contracts Hooks](#use-contracts-hooks)
- [Bundles](#bundles)
- [CLI Usage and Examples](#cli-usage-and-examples)
- [Advanced Usage](#advanced-usage)
- [Example Output](#example-output)
- [JSON Schema](#json-schema)
- [JSON Schema Generation](#json-schema-generation)
- [Exporting Schemas](#exporting-schemas)
- [Developing](#developing)
- [Related](#related)
## Quickstart
Clone your project and `cd` into your contracts folder
```sh
git clone https://github.com/public-awesome/launchpad.git
cd launchpad/contracts/sg721-base/
```
Run `cosmwasm-ts-codegen` to generate your code.
```sh
cosmwasm-ts-codegen generate \
--plugin client \
--schema ./schema \
--out ./ts \
--name SG721 \
--no-bundle
```
The output will be in the folder specified by `--out`, enjoy!
## Usage
You can get started quickly using our `cli` by globally installing via npm:
```
npm install -g @cosmwasm/ts-codegen
```
### Programmatic Usage
For production usage, we recommend setting up a build script that uses the main entry point:
```ts
import codegen from "@cosmwasm/ts-codegen";
codegen({
contracts: [
{
name: "SG721",
dir: "./path/to/sg721/schema",
},
{
name: "Minter",
dir: "./path/to/Minter/schema",
},
],
outPath: "./path/to/code/src/",
// options are completely optional ;)
options: {
bundle: {
bundleFile: "index.ts",
scope: "contracts",
},
types: {
enabled: true,
},
client: {
enabled: true,
},
reactQuery: {
enabled: true,
optionalClient: true,
version: "v4",
mutations: true,
queryKeys: true,
queryFactory: true,
},
recoil: {
enabled: false,
},
messageComposer: {
enabled: false,
},
messageBuilder: {
enabled: false,
},
useContractsHooks: {
enabled: false,
},
},
}).then(() => {
console.log("✨ all done!");
});
```
#### Types
Typescript types and interfaces are generated in separate files so they can be imported into various generated plugins.
[see example output code](https://gist.github.com/pyramation/107d4e8e30dc5eb3ffc07bc3000f4dd0)
#### Types Options
| option | description |
| ------------------------ | --------------------------------------------------------------------- |
| `types.enabled` | enable type generation |
| `types.aliasExecuteMsg` | generate a type alias based on the contract name |
| `types.aliasEntryPoints` | generate type aliases for the entry points based on the contract name |
### Client
The `client` plugin will generate TS client classes for your contracts. This option generates a `QueryClient` for queries as well as a `Client` for queries and mutations.
[see example output code](https://gist.github.com/pyramation/30508678b7563e286f06ccc5ac384817)
#### Client Options
| option | description |
| --------------------------- | ---------------------------------------------------- |
| `client.enabled` | generate TS client classes for your contracts |
| `client.execExtendsQuery` | execute should extend query message clients |
| `client.noImplicitOverride` | should match your tsconfig noImplicitOverride option |
#### Client via CLI
```sh
cosmwasm-ts-codegen generate \
--plugin client
--schema ./schema \
--out ./ts \
--name MyContractName
```
### React Query
Generate [react-query v3](https://react-query-v3.tanstack.com/) or [react-query v4](https://tanstack.com/query/v4/) bindings for your contracts with the `react-query` command.
[see example output code](https://gist.github.com/pyramation/70aef28fd3af0ee164f7711704d3dfc0)
#### React Query Options
| option | description |
| --------------------------- | ---------------------------------------------------------------------------- |
| `reactQuery.enabled` | enable the react-query plugin |
| `reactQuery.optionalClient` | allows contract client to be undefined as the component renders |
| `reactQuery.queryKeys` | generates a const queryKeys object for use with invalidations and set values |
| `reactQuery.queryFactory` | generates a const queryFactory object for useQueries and prefetchQueries use |
| `reactQuery.version` | `v4` uses `@tanstack/react-query` and `v3` uses `react-query` |
| `reactQuery.mutations` | also generate mutations |
| `reactQuery.camelize` | use camelCase style for property names |
#### React Query via CLI
Here is an example without optional client, using v3 for `react-query`, without mutations:
```sh
cosmwasm-ts-codegen generate \
--plugin client \
--plugin react-query \
--schema ./schema \
--out ./ts \
--name MyContractName \
--version v3 \
--no-optionalClient \
--no-mutations
```
Example with optional client, using v4, with mutations:
```sh
cosmwasm-ts-codegen generate \
--plugin react-query \
--schema ./schema \
--out ./ts \
--name MyContractName \
--optionalClient \
--version v4 \
--mutations
```
### Recoil
Generate [recoil](https://recoiljs.org/) bindings for your contracts with the `recoil` command.
[see example output code](https://gist.github.com/pyramation/a9520ccf131177b1841e02a97d7d3731)
#### Recoil via CLI
```sh
cosmwasm-ts-codegen generate \
--plugin recoil \
--schema ./schema \
--out ./ts \
--name MyContractName
```
#### Recoil Options
| option | description |
| ---------------- | ------------------------ |
| `recoil.enabled` | enable the recoil plugin |
### Message Composer
Generate pure message objects with the proper `utf8` encoding and `typeUrl` configured that you can broadcast yourself via `cosmjs` with the `message-composer` command.
[see example output code](https://gist.github.com/pyramation/43320e8b952751a0bd5a77dbc5b601f4)
#### Message Composer via CLI
```sh
cosmwasm-ts-codegen generate \
--plugin message-composer \
--schema ./schema \
--out ./ts \
--name MyContractName
```
#### Message Composer Options
| option | description |
| ------------------------- | --------------------------------- |
| `messageComposer.enabled` | enable the messageComposer plugin |
### Message Builder
Generate raw message jsons for use in your application with the `message-builder` command.
[see example output code](https://gist.github.com/adairrr/b394e62beb9856b0351883f776650f26)
#### Message Builder via CLI
```sh
cosmwasm-ts-codegen generate \
--plugin message-builder \
--schema ./schema \
--out ./ts \
--name MyContractName
```
#### Message Builder Options
| option | description |
| ------------------------ | -------------------------------- |
| `messageBuilder.enabled` | enable the messageBuilder plugin |
### Use Contracts Hooks
| option | description |
| --------------------------- | -------------------------------- |
| `useContractsHooks.enabled` | enable the `useContracts` plugin |
#### Use Contracts Provider Usage
```tsx
import { useChain } from "@cosmos-kit/react";
import { ContractsProvider } from "../path/to/codegen/contracts-context";
export default function YourComponent() {
const { address, getCosmWasmClient, getSigningCosmWasmClient } =
useChain(chainName);
return (
);
}
```
#### Use Contracts Provider Babel/TSC config
If you're using Babel, please make sure include `'@babel/preset-react'` in devDeps and presets in `.babelrc.js`:
```js
presets: ["@babel/typescript", "@babel/env", "@babel/preset-react"];
```
For `tsc`, you should set the `jsx` option to `'react'` in your `tsconfig.json`.
#### Use Contracts Hooks Usage
Once enabled, you can get contracts very simply:
```ts
const { marketplace } = useContracts();
```
```ts
const marketplaceClient = marketplace.signingClient(marketplaceContract);
await marketplaceClient.updateAskPrice({
collection: token.collectionAddr,
price: {
amount,
denom,
},
tokenId,
});
```
### Bundles
The bundler will make a nice package of all your contracts. For example:
```ts
const { MinterQueryClient, useMinterConfigQuery } = contracts.Minter;
const { CwAdminFactoryClient } = contracts.CwAdminFactory;
```
#### Bundler Options
| option | description |
| ------------------- | -------------------------------------------------------------------------------- |
| `bundle.enabled` | enable the bundler plugin |
| `bundle.scope` | name of the scope, defaults to `contracts` (you can use `.` to make more scopes) |
| `bundle.bundleFile` | name of the bundle file |
#### Coding Style
| option | description | default |
| ------------------ | ----------------------------------- | ------- |
| `useShorthandCtor` | Enable using shorthand constructor. | true |
Using shorthand constructor (Might not be transpiled correctly with babel):
```ts
constructor(
protected address: string | undefined,
protected cosmWasmClient: CosmWasmClient | undefined,
protected signingCosmWasmClient: SigningCosmWasmClient | undefined,
private TSign?: new (
client: SigningCosmWasmClient,
sender: string,
contractAddress: string
) => TSign,
private TQuery?: new (
client: CosmWasmClient,
contractAddress: string
) => TQuery,
private TMsgComposer?: new (
sender: string,
contractAddress: string
) => TMsgComposer
) {}
```
Without using shorthand constructor:
```ts
address: string | undefined;
...
TMsgComposer?: new (
sender: string,
contractAddress: string
) => TMsgComposer;
constructor(
address: string | undefined,
...
TMsgComposer?: new (
sender: string,
contractAddress: string
) => TMsgComposer
) {
this.address = address;
...
this.TMsgComposer = TMsgComposer;
}
```
### CLI Usage and Examples
#### Interactive prompt
The CLI is interactive, and if you don't specify an option, it will interactively prompt you.
```sh
cosmwasm-ts-codegen generate
? [plugin] which plugins? (Press to select, to toggle all, to invert selection)
❯◯ client
◯ recoil
◯ react-query
◯ message-composer
```
In this example, you can press space bar to select a number of plugins you wish you enable.
#### Specifying Plugins
Additionally, it will also show you the name of the field (in this case `plugin`) so you can specify the parameter (for example when using CI/CD) on the comand line. Here is an exampl with `--plugin` set to `client` via CLI:
```sh
cosmwasm-ts-codegen generate \
--plugin client
--schema ./schema \
--out ./ts \
--name MyContractName
```
You can specify multiple `--plugin` options using the `generate` command:
```sh
cosmwasm-ts-codegen generate \
--plugin client \
--plugin recoil \
--schema ./schema \
--out ./ts \
--name SG721
```
#### Bypassing the Prompt
All options can be provided so you can bypass the prompt.
For confirm options, you can pass `--no-` to set the value to false. Here is an example without optional client, using v3 for `react-query`, without mutations:
```sh
cosmwasm-ts-codegen generate \
--plugin client \
--plugin react-query \
--schema ./schema \
--out ./ts \
--name MyContractName \
--version v3 \
--no-optionalClient \
--no-mutations
```
Example with optional client, using v4, with mutations:
```sh
cosmwasm-ts-codegen generate \
--plugin react-query \
--schema ./schema \
--out ./ts \
--name MyContractName \
--optionalClient \
--version v4 \
--mutations
```
#### Types Only Option
If needed, you can generate only the types with the `typesOnly` option;
```sh
cosmwasm-ts-codegen generate \
--typesOnly \
--schema ./schema \
--out ./ts \
--name SG721
```
### Advanced Usage
for lower-level access, you can import the various plugins directly:
```ts
import {
generateTypes,
generateClient,
generateReactQuery,
generateRecoil,
generateMessageComposer,
} from "@cosmwasm/ts-codegen";
```
### Example Output
- `cosmwasm-ts-codegen generate --typesOnly`
https://gist.github.com/pyramation/107d4e8e30dc5eb3ffc07bc3000f4dd0
- `cosmwasm-ts-codegen generate --plugin client`
https://gist.github.com/pyramation/30508678b7563e286f06ccc5ac384817
- `cosmwasm-ts-codegen generate --plugin react-query`
https://gist.github.com/pyramation/70aef28fd3af0ee164f7711704d3dfc0
- `cosmwasm-ts-codegen generate --plugin recoil`
https://gist.github.com/pyramation/a9520ccf131177b1841e02a97d7d3731
- `cosmwasm-ts-codegen generate --plugin message-composer`
https://gist.github.com/pyramation/43320e8b952751a0bd5a77dbc5b601f4
- `cosmwasm-ts-codegen generate --plugin message-builder`
https://gist.github.com/adairrr/b394e62beb9856b0351883f776650f26
### JSON Schema
We generate code from the [JSON Schema](https://json-schema.org/) exported from CosmWasm smart contracts.
### JSON Schema Generation
Currently you have to have the JSON Schema output. Here is an example to start.
First, get the Rust contracts and run `cargo build`:
```sh
git clone git@github.com:public-awesome/stargaze-contracts.git
cd stargaze-contracts
cargo build
```
now build the schema with `cargo schema`
```sh
cd contracts/sg721/
cargo schema
```
### Exporting Schemas
#### `cosmwasm v1.1` Example
Using the new `write_api` method, you can export schemas:
```rs
use cosmwasm_schema::write_api;
use cw4_group::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
fn main() {
write_api! {
instantiate: InstantiateMsg,
execute: ExecuteMsg,
query: QueryMsg,
}
}
```
#### `cosmwasm_std` Example
Here is a legacy example:
```rs
use cosmwasm_std::{Addr, CosmosMsg, Empty};
export_schema_with_title(&schema_for!(MinterData), &out_dir, "MinterResponse");
export_schema_with_title(&schema_for!(Addr), &out_dir, "StakingResponse");
export_schema_with_title(&schema_for!(Addr), &out_dir, "DaoResponse");
export_schema_with_title(
&schema_for!(CosmosMsg),
&out_dir,
"CosmosMsg_for_Empty",
);
```
## Developing
### Initial setup
```
yarn
yarn bootstrap
```
### Building
```
yarn build
```
### Tests
Then `cd` into a package and run the tests
```
cd ./packages/wasm-ast-types
yarn test:watch
```
### Working with ASTs
See the [docs](https://github.com/CosmWasm/ts-codegen/blob/main/packages/ast/README.md) in the `ast` package.
## Related
Checkout these related projects:
- [@cosmology/telescope](https://github.com/hyperweb-io/telescope) a "babel for the Cosmos", Telescope is a TypeScript Transpiler for Cosmos Protobufs.
- [chain-registry](https://github.com/hyperweb-io/chain-registry) an npm module for the official Cosmos chain-registry.
- [cosmos-kit](https://github.com/hyperweb-io/cosmos-kit) A wallet connector for the Cosmos ⚛️
- [create-cosmos-app](https://github.com/hyperweb-io/create-cosmos-app) set up a modern Cosmos app by running one command.
- [starship](https://github.com/hyperweb-io/starship) a k8s-based unified development environment for Cosmos Ecosystem
----------------------------------
Developing
# Developing
## Initial setup
```
yarn
yarn bootstrap
```
## Building
```
yarn build
```
## Tests
Then `cd` into a package and run the tests
```
cd ./packages/wasm-ast-types
yarn test:watch
```
## Working with ASTs
See the [docs](/ts-codegen/developing/ast) in the `wasm-ast-types` package.
----------------------------------
Ast
## Working with ASTs
### 1 edit the fixture
edit `./scripts/fixture.ts`, for example:
```js
// ./scripts/fixture.ts
export interface InstantiateMsg {
admin?: string | null;
members: Member[];
}
```
### 2 run AST generator
```
yarn test:ast
```
### 3 look at the JSON produced
```
code ./scripts/test-output.json
```
We use the npm module `ast-stringify` to strip out unnecessary props, and generate a JSON for reference.
You will see a `File` and `Program`... only concern yourself with the `body[]`:
```json
{
"type": "File",
"errors": [],
"program": {
"type": "Program",
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExportNamedDeclaration",
"exportKind": "type",
"specifiers": [],
"source": null,
"declaration": {
"type": "TSInterfaceDeclaration",
"id": {
"type": "Identifier",
"name": "InstantiateMsg"
},
"body": {
"type": "TSInterfaceBody",
"body": [
{
"type": "TSPropertySignature",
"key": {
"type": "Identifier",
"name": "admin"
},
"computed": false,
"optional": true,
"typeAnnotation": {
"type": "TSTypeAnnotation",
"typeAnnotation": {
"type": "TSUnionType",
"types": [
{
"type": "TSStringKeyword"
},
{
"type": "TSNullKeyword"
}
]
}
}
},
{
"type": "TSPropertySignature",
"key": {
"type": "Identifier",
"name": "members"
},
"computed": false,
"typeAnnotation": {
"type": "TSTypeAnnotation",
"typeAnnotation": {
"type": "TSArrayType",
"elementType": {
"type": "TSTypeReference",
"typeName": {
"type": "Identifier",
"name": "Member"
}
}
}
}
}
]
}
}
}
],
"directives": []
},
"comments": []
}
```
### 4 code with `@babel/types` using the JSON as a reference
NOTE: 4 continued ideally you should be writing a test with your generator!
```js
import * as t from '@babel/types';
export const createNewGenerator = () => {
return t.exportNamedDeclaration(
t.tsInterfaceDeclaration(
t.identifier('InstantiateMsg'),
null,
[],
t.tsInterfaceBody([
// ... more code ...
])
)
);
};
```