Giter Site home page Giter Site logo

ts-codegen's Introduction

@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 to learn how to use ts-codegen!

Table of contents

Quickstart

Clone your project and cd into your contracts folder

git clone https://github.com/public-awesome/launchpad.git
cd launchpad/contracts/sg721-base/

Run cosmwasm-ts-codegen to generate your code.

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:

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

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

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

cosmwasm-ts-codegen generate \
    --plugin client
    --schema ./schema \
    --out ./ts \
    --name MyContractName

React Query

Generate react-query v3 or react-query v4 bindings for your contracts with the react-query command.

see example output code

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:

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:

cosmwasm-ts-codegen generate \
    --plugin react-query \
    --schema ./schema \
    --out ./ts \
    --name MyContractName \
    --optionalClient \
    --version v4 \
    --mutations

Recoil

Generate recoil bindings for your contracts with the recoil command.

see example output code

Recoil via CLI

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

Message Composer via CLI

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

Message Builder via CLI

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

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 (
    <ContractsProvider
      contractsConfig={{
        address,
        getCosmWasmClient,
        getSigningCosmWasmClient,
      }}
    >
        <SomeCoolComponent />
    </ContractsProvider>
  )
};

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:

 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:

const { marketplace } = useContracts();
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:

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):

  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:

  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.

cosmwasm-ts-codegen generate
? [plugin] which plugins? (Press <space> to select, <a> to toggle all, <i> 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:

cosmwasm-ts-codegen generate \
    --plugin client
    --schema ./schema \
    --out ./ts \
    --name MyContractName

You can specify multiple --plugin options using the generate command:

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-<name> to set the value to false. Here is an example without optional client, using v3 for react-query, without mutations:

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:

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;

cosmwasm-ts-codegen generate \
          --typesOnly \
          --schema ./schema \
          --out ./ts \
          --name SG721

Advanced Usage

for lower-level access, you can import the various plugins directly:

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 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:

git clone [email protected]:public-awesome/stargaze-contracts.git
cd stargaze-contracts
cargo build

now build the schema with cargo schema

cd contracts/sg721/
cargo schema

Exporting Schemas

cosmwasm v1.1 Example

Using the new write_api method, you can export schemas:

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:

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<Empty>),
      &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 in the wasm-ast-types package.

Related

Checkout these related projects:

  • @cosmology/telescope a "babel for the Cosmos", Telescope is a TypeScript Transpiler for Cosmos Protobufs.
  • chain-registry an npm module for the official Cosmos chain-registry.
  • cosmos-kit A wallet connector for the Cosmos ⚛️
  • create-cosmos-app set up a modern Cosmos app by running one command.
  • starship a k8s-based unified development environment for Cosmos Ecosystem

Credits

🛠 Built by Cosmology — if you like our tools, please consider delegating to our validator ⚛️

ts-codegen's People

Contributors

adairrr avatar m-daeva avatar noahsaso avatar pyramation avatar zetazzz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

ts-codegen's Issues

move away from json-schema-to-typescript

Client type

Currently ts-codegen use SigningCosmWasmClient for the client instead of CosmWasmSigner?
CosmWasmSigner is just a wrapper of SigningCosmWasmClient in ts-relayer.
But, I think it's more useful.

One of the reasons to prefer CosmWasmSigner is that it contains senderAddress to include as an argument of the many methods which SigningCosmWasmClient has.

Sample Project Generation

CosmWasm projects usually have a setup including a contracts and packages folder: cw-plus and dao dao as a couple examples.
I think ts-codegen should have a sample project generation file in the docs to make using this tool easier.

codegen.ts

import codegen, { ContractFile } from "@cosmwasm/ts-codegen";
import { glob } from "glob";

glob("../@(contracts|packages)/*/schema", (err, matches) => {
  if (err) console.log(err);

  let contracts: ContractFile[] = [];

  matches.forEach((x) => {
    contracts.push({
      name: x.split("/")[2],
      dir: x,
    });
  });

  codegen({
    contracts,
    outPath: "./generated",

    options: {
      bundle: {
        bundleFile: "index.ts",
        scope: "contracts",
      },
      types: {
        enabled: true,
      },
      client: {
        enabled: true,
      },
    },
  }).then(() => {
    console.log("✨ all done!");
  });
});

I used glob, because this is how ts-codegen's utils.readSchemas interprets paths. If a valid path is not given from windows, then ts-codegen will not generate anything.

codegen errors for query case without parameters

related CosmWasm/cosmwasm#1416

example https://github.com/grod220/ts-codegen-example

schema https://gist.github.com/pyramation/97af26385c9348688c74e849898ce419

the generated code that causes an issue (the enum):

  "execute": {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "ExecuteMsg",
    "oneOf": [
      {
        "type": "string",
        "enum": [
          "accept_ownership"
        ]
      },
      {
        "description": "Due to some chains being permissioned via governance, we must instantiate this contract first and give ownership access to Rover contract with this action after both are independently deployed.",
        "type": "object",
        "required": [
          "propose_new_owner"
        ],
        "properties": {
          "propose_new_owner": {
            "type": "object",
            "required": [
              "new_owner"
            ],
            "properties": {
              "new_owner": {
                "type": "string"
              }
            }
          }
        },
        "additionalProperties": false
      },
...

idl-version warnings

This isn't a priority or anything, but in the future it would be nice to parse the idl_version as a semver value and make sure it satisfies the semver requirement of ^1.0.0 (or whatever the supported version is at the time). And just crash otherwise with IDL version {idl_version} not supported.

Support CosmWasm 1.1 Schemas

Really excited for CosmWasm 1.1 schemas... would be great to get support for that so we can start using them.

Generated ts client files misses override modifier

The generated client file from json schema from cw_serde could not work properly since it misses the override modifier.
For instance, the generated Poap.client.ts shows:

export class PoapQueryClient implements PoapReadOnlyInterface {
  client: CosmWasmClient;
  contractAddress: string;

  methods...
}
export class PoapClient extends PoapQueryClient implements PoapInterface {
  client: SigningCosmWasmClient;
  sender: string;
  contractAddress: string;
 
  methods...
}

Then, thhe error shows:

../types/contracts/poap/Poap.client.ts:133:3 - error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'PoapQueryClient'.

133   client: SigningCosmWasmClient;
      ~~~~~~
../types/contracts/poap/Poap.client.ts:135:3 - error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'PoapQueryClient'.

135   contractAddress: string;

After adding override modifier to PoapClient property can solve the issue, like:

export class PoapClient extends PoapQueryClient implements PoapInterface {
  override client: SigningCosmWasmClient;
  sender: string;
  override contractAddress: string;
 
  methods...
}

Conflict with "no implicit override" TS rule.

In case you have this rule active in your tsconfig, you have to update manually to include override each time they are generated. Will be great to be included in the generation 😄

image

Raw Msg MessageComposer

It would be great if we could generate a "raw" message composer as well, or have an optional parameter to the message composer so that we can build the "raw" messages like this:

{
  install_module: {
    init_msg: initMsg,
    module,
  }

instead of the MsgExecuteContractEncodeObject (which you need to deconstruct to msg.value.msg otherwise).

The code would probably look like the following:

  installModule = (
    {
      initMsg,
      module,
    }: {
      initMsg?: Binary
      module: ModuleInfo
    },
     // this return typing below does not exist yet but would be really nice!
  ): InstallModuleExecMsg => ({
    install_module: {
      init_msg: initMsg,
      module,
    },
  })

(vs currently):

  installModule = (
    {
      initMsg,
      module,
    }: {
      initMsg?: Binary
      module: ModuleInfo
    },
    funds?: Coin[]
  ): MsgExecuteContractEncodeObject => {
    return {
      typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract',
      value: MsgExecuteContract.fromPartial({
        sender: this.sender,
        contract: this.contractAddress,
        msg: toUtf8(
          JSON.stringify({
            install_module: {
              init_msg: initMsg,
              module,
            },
          })
        ),
        funds,
      }),
    }
  }

query and execute messages with same name creates collisions

Currently we're generating two TS clients as classes with the codegen: one class that is readonly for the queries, and a 2nd that extends via inheritance this class for the execute messages. This essentially means the names currently must be unique.

The issue is that if you have an identical method name on a query and execute, you end up with a naming collision.

One idea is to potentially come up with a recommended convention to keep names unique across queries/executes, This does make some sense, but some have brought up a good point that it is sub-optimal to put constraints on contract message naming.

the current "fix" is to not create name collisions between query and execute messages: DA0-DA0/dao-contracts#369

However, the question remains, should we build a way to split clients into two instead of using inheritance where all contract names are unique?

Query enum tuple format missing argument

When you have a query type such as:

#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
    #[returns(String)]
    AllPreviousOwners(String),

The generated typescript will be missing the String argument required for this query:

  allPreviousOwners = async (): Promise<String> => {
    return this.client.queryContractSmart(this.contractAddress, {
      all_previous_owners: {}
    });
  };

Reproducible example here: https://github.com/grod220/ts-codegen-example/blob/master/contracts/account-nft/src/msg/query.rs#L32-L33

some messages are not objects but instead scalar values

Here is the latest export for ExecuteMsg (in Typescript)

export type ExecuteMsg = {
  mint: {
    [k: string]: unknown;
  };
} | {
  set_whitelist: {
    whitelist: string;
    [k: string]: unknown;
  };
} | {
  update_start_time: Timestamp;
} | {
  update_per_address_limit: {
    per_address_limit: number;
    [k: string]: unknown;
  };
} | {
  mint_to: {
    recipient: string;
    [k: string]: unknown;
  };
} | {
  mint_for: {
    recipient: string;
    token_id: number;
    [k: string]: unknown;
  };
} | {
  withdraw: {
    [k: string]: unknown;
  };
};

I noticed that update_start_time is the only one that doesn't take an object. Every other message uses either an empty object or an object with props.

update_start_time: Timestamp

Is there a convention? Or should we account for this in the cosmwasm-typescript-gen

add event emitter option for client to support messages composer

Some users may want to control state a bit more than what client.execute provides, which is the default way the client operates. For example, client.execute current does this:

  1. composes the messages
  2. signs the message
  3. broadcasts the message

The issue is that, during #2, the user may be signing via keplr, and technically there is more state involved, if perhaps you wanted to display a spinning loader to the user interfaces.

Example of separating these out using the current message composer option:
https://github.com/EquilibriumEtf/frontend/blob/main/contexts/tx.tsx
https://gist.github.com/pyramation/0ce63b6026cc15a68c46454af2c879de

However, this implementation is conflating UI and transaction state. I think a solid implementation could involve adding an option to the client option that enables an emitter, or some state object that can emit state to objects outside of the class instance during a transaction, potentially messages/state like is_signing, is_broadcasting

Generated client contains wrong typings for "fee" parameter

Hello, first of all thanks for the package, it's so great and easy to use!

I'm trying to generate the Query/Execute clients starting from my own schema, but I'm noticing that all methods which contain the "fee" parameter have these typings:

fee: number | StdFee = "auto"

When it should be:

fee: number | StdFee | "auto" = "auto"

The fact that the default value "auto" is not included in the types possibilities makes TS angry. I could fix each one by hand, but then if I regenerate I get the same problem.

Remove undefined typings from Recoil generator

The query client (CosmWasmClient) will either return a valid connection or throw an error. The Recoil generator assumes that it can return undefined, when in fact it cannot. All of the selectors have if (!client) return in them as well as typings containing undefined, which forces us to do unnecessary type checks. Let's remove all the undefined stuff!

Enums are not translated to types

In my JSON schema I have this:

"CodeIdType": {
    "type": "string",
    "enum": [
      "Proxy",
      "Multisig",
      "Govec",
      "Staking"
    ]
}

CodeIdType is referenced in the generated TS, but the type itself is not generated. I expect to have something like:

export type CodeIdType = "Proxy" | "Multisig" | "Govec" | "Staking";

Just like string aliases are currently translated, for example:

"Addr": {
    "type": "string"
}

Becomes

export type Addr = string;

Mutation property type error in generated react query file

The generated react query from cw721-base has the error in useCw721BaseMintMutation function from the Cw721BaseMintMutation with wrong type msg property.
The msg in Cw721BaseMintMutation is using generated msg whose properties are in snake-case, it mismatches the client mint function to use the object with camel-case naming:

Here is an example:

export interface Cw721BaseMintMutation {
  client: Cw721BaseClient;
  msg: MintMsgForNullable_Empty;
  args?: {
    fee?: number | StdFee | "auto";
    memo?: string;
    funds?: Coin[];
  };
}
export function useCw721BaseMintMutation(options?: Omit<UseMutationOptions<ExecuteResult, Error, Cw721BaseMintMutation>, "mutationFn">) {
  return useMutation<ExecuteResult, Error, Cw721BaseMintMutation>(({
    client,
    msg,
    args: {
      fee,
      memo,
      funds
    } = {}
  }) => client.mint(msg, fee, memo, funds), options);

The structure of msg are snake case naming:

export interface MintMsgForNullable_Empty {
  extension?: Empty | null;
  owner: string;
  token_id: string;
  token_uri?: string | null;
}

The client mint required args are camel case naming:

mint = async ({
    extension,
    owner,
    tokenId,
    tokenUri
  }: {
    extension?: Empty;
    owner: string;
    tokenId: string;
    tokenUri?: string;
  }, fee: number | StdFee | "auto" = "auto", memo?: string, funds?: Coin[]): Promise<ExecuteResult> => {
    return await this.client.execute(this.sender, this.contractAddress, {
      mint: {
        extension,
        owner,
        token_id: tokenId,
        token_uri: tokenUri
      }
    }, fee, memo, funds);
  };

Generate crashes with Empty enum msg

Having an empty QueryMsg enum:

pub enum QueryMsg {}

https://github.com/DA0-DA0/dao-contracts/pull/370/files#diff-840200e9bacf09b0b4728e7462feae7f2bd9cfbc92ae5d3cfe330c1a47b0ff9cR22

Causes an error when generating the ts files:

SyntaxError: '=>' expected. (9:1)
  7 |
  8 | export type QueryMsg = ()
> 9 |
    | ^
    at Ve (/home/runner/work/dao-contracts/dao-contracts/types/node_modules/json-schema-to-typescript/node_modules/prettier/parser-typescript.js:1:[15](https://github.com/DA0-DA0/dao-contracts/runs/7050221031?check_suite_focus=true#step:5:16)607)
    at vz (/home/runner/work/dao-contracts/dao-contracts/types/node_modules/json-schema-to-typescript/node_modules/prettier/parser-typescript.js:280:5919)
    at Object.yz [as parse] (/home/runner/work/dao-contracts/dao-contracts/types/node_modules/json-schema-to-typescript/node_modules/prettier/parser-typescript.js:280:6242)
    at Object.parse (/home/runner/work/dao-contracts/dao-contracts/types/node_modules/json-schema-to-typescript/node_modules/prettier/index.js:7334:23)
    at coreFormat (/home/runner/work/dao-contracts/dao-contracts/types/node_modules/json-schema-to-typescript/node_modules/prettier/index.js:8645:18)
    at formatWithCursor2 (/home/runner/work/dao-contracts/dao-contracts/types/node_modules/json-schema-to-typescript/node_modules/prettier/index.js:8837:18)
    at /home/runner/work/dao-contracts/dao-contracts/types/node_modules/json-schema-to-typescript/node_modules/prettier/index.js:37226:12
    at Object.format (/home/runner/work/dao-contracts/dao-contracts/types/node_modules/json-schema-to-typescript/node_modules/prettier/index.js:37240:12)
    at Object.format (/home/runner/work/dao-contracts/dao-contracts/types/node_modules/json-schema-to-typescript/dist/src/formatter.js:20:23)
    at /home/runner/work/dao-contracts/dao-contracts/types/node_modules/json-schema-to-typescript/dist/src/index.js:[17](https://github.com/DA0-DA0/dao-contracts/runs/7050221031?check_suite_focus=true#step:5:18)0:45 {
  loc: { start: { line: 9, column: 1 } },
  codeFrame: '  7 |\n  8 | export type QueryMsg = ()\n> 9 |\n    | ^'
}

https://github.com/DA0-DA0/dao-contracts/runs/7050221031?check_suite_focus=true#step:5:14

The json schema when exporting an empty enum:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "QueryMsg",
  "type": "string",
  "enum": []
}

recoil example or add to codegen

for recoil example, your code export will need a chain.ts

should have this selector in it:

export const cosmWasmClientSelector = selector({
  key: 'cosmWasmClient',
  get: () => CosmWasmClient.connect(CHAIN_RPC_ENDPOINT),
})

[react] context generation for contract client instances

We need some helpers to create contexts/providers for the client instances.

A good example of the client here:
https://github.com/EquilibriumEtf/frontend/blob/53e24aa7992bdaad85ec2a7c02a2e604a2d40897/client/core/index.ts#L27
https://gist.github.com/pyramation/05cebb95208accbcc76fbbe273211167

example of provider here:
https://github.com/EquilibriumEtf/frontend/blob/53e24aa7992bdaad85ec2a7c02a2e604a2d40897/client/react/client/EquilibriumProvider.tsx#L8
https://gist.github.com/pyramation/9db71d59e66694160d1194d291355c04

With a few changes:

  • instead of all instances in one massive context, potentially have context for each client
  • instead of wallet data, potentially just use address: string or whatever data is required

Error: contact maintainers [unknown type]: array

Dear team,

I am trying to generate the typescript files from a working cosmwasm contract which has been deployed locally as well as on Malaga.
The contract messages need to pass more than one argument and we use arrays a lot for that reason.

Error: contact maintainers [unknown type]: array
    at getType (/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/utils/types.js:76:13)
    at getArrayTypeFromType (/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/utils/types.js:59:24)
    at getPropertyType (/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/utils/types.js:132:16)
    at /home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/utils/types.js:236:7
    at Array.map (<anonymous>)
    at createTypedObjectParams (/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/utils/types.js:186:26)
    at createPropertyFunctionWithObjectParamsForExec (/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/wasm.js:137:49)
    at /home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/wasm.js:114:12
    at Array.map (<anonymous>)
    at Object.createExecuteInterface (/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/wasm.js:111:59)
{
  type: 'object',
  required: [ 'graph', 'graph_id' ],
  properties: {
    graph: { type: 'array', items: [Object], minItems: 0 },
    graph_id: { type: 'integer', format: 'int32' }
  },
  additionalProperties: true
} graph
/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/utils/types.js:76
      throw new Error('contact maintainers [unknown type]: ' + type);
            ^

Error: contact maintainers [unknown type]: array
    at getType (/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/utils/types.js:76:13)
    at getArrayTypeFromType (/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/utils/types.js:59:24)
    at getPropertyType (/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/utils/types.js:132:16)
    at /home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/utils/types.js:242:28
    at Array.map (<anonymous>)
    at createTypedObjectParams (/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/utils/types.js:186:26)
    at createPropertyFunctionWithObjectParamsForExec (/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/wasm.js:137:49)
    at /home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/wasm.js:114:12
    at Array.map (<anonymous>)
    at Object.createExecuteInterface (/home/peppi/.nvm/versions/node/v18.7.0/lib/node_modules/@cosmwasm/ts-codegen/node_modules/wasm-ast-types/main/wasm.js:111:59)

Node.js v18.7.0

`

Support for types generic over `Empty`

For the case where CosmosMsg_for_Empty is used in ExecuteMsg_for_Empty over a generic default to Empty,
which is in the definitions section of the schema, does not get type generated automatically.

However, when we generate it separately due to the casing, its type name is compiled to CosmosMsgFor_Empty.

Can we add this to a part of some default wasm message types?

Generate doesn't support optional lists in ExecuteMsg schema

Steps to reproduce:

Error:

/usr/local/lib/node_modules/cosmwasm-typescript-gen/node_modules/wasm-ast-types/main/wasm.js:70
      throw new Error('what is type: ' + type);
            ^

Error: what is type: array
    at getType (/usr/local/lib/node_modules/cosmwasm-typescript-gen/node_modules/wasm-ast-types/main/wasm.js:70:13)
    at getPropertyType (/usr/local/lib/node_modules/cosmwasm-typescript-gen/node_modules/wasm-ast-types/main/wasm.js:134:12)
    at /usr/local/lib/node_modules/cosmwasm-typescript-gen/node_modules/wasm-ast-types/main/wasm.js:283:28
    at Array.map (<anonymous>)
    at createTypedObjectParams (/usr/local/lib/node_modules/cosmwasm-typescript-gen/node_modules/wasm-ast-types/main/wasm.js:282:26)
    at createPropertyFunctionWithObjectParamsForExec (/usr/local/lib/node_modules/cosmwasm-typescript-gen/node_modules/wasm-ast-types/main/wasm.js:312:13)
    at /usr/local/lib/node_modules/cosmwasm-typescript-gen/node_modules/wasm-ast-types/main/wasm.js:246:12
    at Array.map (<anonymous>)
    at Object.createExecuteInterface (/usr/local/lib/node_modules/cosmwasm-typescript-gen/node_modules/wasm-ast-types/main/wasm.js:243:59)
    at _callee$ (/usr/local/lib/node_modules/cosmwasm-typescript-gen/main/generate.js:113:29)

See: DA0-DA0/dao-contracts#347 (comment)

[Request] Option for types path in client generation

Hey!

It's not prioritary but will be great to have an extra property in the client config in order to define in what path are your types.
I tried to build types for one side and clients for the other side and got that problem client is important types from the same path.
I would like to have them in different folders since that will be easier for me to export it in a npm package.

Thanks and as always great job! 🚀

convert types for arguments into their own interfaces

export interface SG721ReadOnlyInterface {
  contractAddress: string;
  ownerOf: ({includeExpired, tokenId}:{includeExpired?: boolean, tokenId?: string}) => Promise<OwnerOfResponse>;
}

could become

export interface OwnerOfParams {
  includeExpired?: boolean;
  tokenId?: string;
}

export interface SG721ReadOnlyInterface {
  contractAddress: string;
  ownerOf: (value: OwnerOfParams) => Promise<OwnerOfResponse>;
}

Pedantic eslint complaints

Got some messages from eslint. Maybe you can adjust for the empty objects we love in Rust.

Code:

export type ExecuteMsg =
  | {
      bond: {};
    }
  | ...

Error message:

  19:11  error  Don't use `{}` as a type. `{}` actually means "any non-nullish value".
- If you want a type meaning "any object", you probably want `Record<string, unknown>` instead.
- If you want a type meaning "any value", you probably want `unknown` instead.
- If you want a type meaning "empty object", you probably want `Record<string, never>` instead  @typescript-eslint/ban-types

I just manually updated mine to Record<string, never>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.