Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
ratik committed Apr 8, 2023
0 parents commit 8cd5dc6
Show file tree
Hide file tree
Showing 12 changed files with 3,775 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules

/.jest
/packages/**/dist/

/.yarn/*
/.pnp.*
/src/generated/*
45 changes: 45 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"rules": {
"prettier/prettier": ["error", {}, { "usePrettierrc": true }],
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{ "ignoreRestSiblings": true }
],
"no-useless-return": ["error"],
"arrow-body-style": ["error", "as-needed"]
},
"overrides": [
{
"files": ["*.test.ts", "*.test.tsx"],
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
},
{
"files": ["*.js"],
"rules": {
"@typescript-eslint/explicit-module-boundary-types": "off"
}
}
],
"settings": {}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"useTabs": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all"
}
7 changes: 7 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": []
}
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Contracts2TS

Contracts2TS is a command line tool that helps you generate TypeScript code for CosmWasm smart contracts from their Rust source code. The generated code includes TypeScript types, clients, and other utilities to interact with the smart contracts.

## Installation

You can install Contracts2TS globally using npm:

```
npm install -g @neutron-org/contracts2ts
```

## Usage

To generate TypeScript code for your smart contracts, run the following command:

```
contracts2ts --src=<path to contracts> --out=<path to output> --scope=<scope>
```

### NPX Usage

If you don't want to install the package globally, you can use `npx` to run the command:

```
npx @neutron-org/contracts2ts --src=<path to contracts> --out=<path to output> --scope=<scope>
```

### Arguments

- `--src`: The path to the contracts directory.
- `--out`: The path to the output directory where the generated TypeScript code will be saved.
- `--scope`: The scope for the generated TypeScript code.

### Example

```
contracts2ts --src=./neutron-dao --out=./dao.ts --scope=tge
```

This command will generate TypeScript code for the smart contracts located in the `./neutron-dao` directory and save the output in the `./dao.ts` directory with the scope `tge`.

## How it works

The script does the following:

1. Validates the command line arguments.
2. Finds all the smart contract directories by searching for `Cargo.toml` files.
3. Executes `cargo schema` for each smart contract to generate schema files.
4. Generates TypeScript code using `@cosmwasm/ts-codegen` for each smart contract.

## Troubleshooting

If you encounter any issues or errors, make sure your smart contract directories have the necessary `Cargo.toml` and schema files. If the schema files are missing or not up-to-date, you can run `cargo schema` manually in each smart contract directory to generate them.
80 changes: 80 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/usr/bin/env node
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ts_codegen_1 = __importDefault(require("@cosmwasm/ts-codegen"));
const cli_argument_parser_1 = require("cli-argument-parser");
const fs_1 = require("fs");
const child_process_1 = require("child_process");
const node_recursive_directory_1 = __importDefault(require("node-recursive-directory"));
const path_1 = __importDefault(require("path"));
(async () => {
const contractPath = cli_argument_parser_1.cliArguments.src;
if (!contractPath) {
throw new Error('Contract path is not defined');
}
const outputDir = cli_argument_parser_1.cliArguments.out;
if (!outputDir) {
throw new Error('Output path is not defined');
}
const scope = cli_argument_parser_1.cliArguments.scope;
if (!scope) {
throw new Error('Scope is not defined');
}
const buildSchema = cli_argument_parser_1.cliArguments.buildSchema === 'false' ? false : true;
const dir = path_1.default.join(process.cwd(), contractPath, '/contracts');
const files = (await (0, node_recursive_directory_1.default)(dir)).filter((file) => file.endsWith('Cargo.toml'));
const contracts = files.map((file) => ({
dir: path_1.default.dirname(file),
name: path_1.default.basename(path_1.default.dirname(file)),
}));
if (buildSchema) {
for (const contract of contracts) {
await new Promise((r, rj) => (0, child_process_1.exec)('cargo schema', { cwd: contract.dir }, (err, stdout, stderr) => {
if (err) {
console.error(err);
rj(err);
}
else {
console.log(stdout);
console.error(stderr);
r(true);
}
}));
}
}
const contractsForCodegen = await Promise.all(contracts.map(async (contract) => {
//check if schema exists
const schemaPath = path_1.default.join(contract.dir, '/schema/raw');
const schemaExists = await fs_1.promises
.access(schemaPath)
.then(() => true)
.catch(() => false);
return {
name: contract.name,
dir: schemaExists ? schemaPath : path_1.default.join(contract.dir, '/schema'),
};
}));
await (0, ts_codegen_1.default)({
contracts: contractsForCodegen,
outPath: path_1.default.join(process.cwd(), outputDir),
options: {
bundle: {
bundleFile: 'index.ts',
scope,
},
types: {
enabled: true,
},
client: {
enabled: true,
},
messageComposer: {
enabled: false,
},
},
});
console.log('Done');
})();
33 changes: 33 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "@neutron-org/contracts2ts",
"version": "1.0.2",
"main": "index.js",
"license": "MIT",
"author": "Sergey Ratiashvili <[email protected]>",
"bin": "lib/index.js",
"repository": {
"type": "git",
"url": "https://github.com/neutron-org/contracts2ts"
},
"scripts": {
"start": "ts-node src/index.ts",
"build": "tsc -p tsconfig.json",
"lint": "eslint ./src",
"lint-fix": "eslint ./src --fix"
},
"dependencies": {
"@cosmwasm/ts-codegen": "^0.25.2",
"cli-argument-parser": "^0.6.7",
"node-recursive-directory": "^1.2.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.57.1",
"@typescript-eslint/parser": "^5.57.1",
"eslint": "^8.37.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"prettier": "^2.8.7",
"ts-node": "^10.9.1",
"typescript": "^5.0.4"
}
}
89 changes: 89 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env node

import codegen from '@cosmwasm/ts-codegen';
import { cliArguments } from 'cli-argument-parser';
import { promises as fs } from 'fs';
import { exec } from 'child_process';
import getFiles from 'node-recursive-directory';
import path from 'path';

(async () => {
const contractPath = cliArguments.src;
if (Object.keys(cliArguments).length !== 3) {
console.log(
'Usage: contracts2ts --src <path to contracts> --out <path to output> --scope <scope>',
);
process.exit(0);
}
if (!contractPath) {
throw new Error('Contract path is not defined');
}
const outputDir = cliArguments.out;
if (!outputDir) {
throw new Error('Output path is not defined');
}
const scope = cliArguments.scope;
if (!scope) {
throw new Error('Scope is not defined');
}
const buildSchema = cliArguments.buildSchema === 'false' ? false : true;
const dir = path.join(process.cwd(), contractPath, '/contracts');
const files = (await getFiles(dir)).filter((file) =>
file.endsWith('Cargo.toml'),
);
const contracts: { dir: string; name: string }[] = files.map((file) => ({
dir: path.dirname(file),
name: path.basename(path.dirname(file)),
}));
if (buildSchema) {
for (const contract of contracts) {
await new Promise((r, rj) =>
exec('cargo schema', { cwd: contract.dir }, (err, stdout, stderr) => {
if (err) {
console.error(err);
rj(err);
} else {
console.log(stdout);
console.error(stderr);
r(true);
}
}),
);
}
}
const contractsForCodegen = await Promise.all(
contracts.map(async (contract) => {
//check if schema exists
const schemaPath = path.join(contract.dir, '/schema/raw');
const schemaExists = await fs
.access(schemaPath)
.then(() => true)
.catch(() => false);
return {
name: contract.name,
dir: schemaExists ? schemaPath : path.join(contract.dir, '/schema'),
};
}),
);

await codegen({
contracts: contractsForCodegen,
outPath: path.join(process.cwd(), outputDir),
options: {
bundle: {
bundleFile: 'index.ts',
scope,
},
types: {
enabled: true,
},
client: {
enabled: true,
},
messageComposer: {
enabled: false,
},
},
});
console.log('Done');
})();
13 changes: 13 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "ESNext",
"types": ["node"],
"module": "commonjs",
"lib": ["esnext"],
"outDir": "lib",
"resolveJsonModule": true,
"esModuleInterop": true
},
"include": ["./src/**/*"],
"exclude": ["./src/**/*.test.ts"]
}
Loading

0 comments on commit 8cd5dc6

Please sign in to comment.