@clarigen/cli 1.0.0-next.16 → 1.0.0-next.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@clarigen/cli",
3
3
  "description": "A CLI for generating a Typescript interface for a Clarity contract.",
4
4
  "author": "Hank Stoever",
5
- "version": "1.0.0-next.16",
5
+ "version": "1.0.0-next.19",
6
6
  "license": "MIT",
7
7
  "types": "./dist/index.d.ts",
8
8
  "main": "./dist/index.js",
@@ -24,7 +24,8 @@
24
24
  "lint": "eslint \"src/**/*.{ts,tsx}\" && prettier --check src/**/*.ts",
25
25
  "typecheck": "tsc --noEmit -p tsconfig-test.json",
26
26
  "prepublishOnly": "yarn build",
27
- "demo": "yarn build && node bin/run"
27
+ "demo": "yarn build && node bin/run",
28
+ "publish:dev": "yalc publish --push"
28
29
  },
29
30
  "bin": {
30
31
  "clarigen": "./bin/run"
@@ -49,9 +50,9 @@
49
50
  "ts-node": "^9.1.1"
50
51
  },
51
52
  "dependencies": {
52
- "@clarigen/claridocs": "1.0.0-next.16",
53
- "@clarigen/core": "1.0.0-next.16",
54
- "@clarigen/native-bin": "1.0.0-next.16",
53
+ "@clarigen/claridocs": "1.0.0-next.19",
54
+ "@clarigen/core": "1.0.0-next.19",
55
+ "@clarigen/native-bin": "1.0.0-next.19",
55
56
  "@ltd/j-toml": "1.12.2",
56
57
  "@oclif/command": "^1.8.0",
57
58
  "@oclif/config": "^1.17.0",
@@ -60,11 +61,12 @@
60
61
  "chokidar": "3.5.1",
61
62
  "micro-stacks": "^0.2.0",
62
63
  "ora": "5.4.0",
64
+ "prettier": "2.6.2",
63
65
  "reserved-words": "0.1.2",
64
66
  "toposort": "2.0.2"
65
67
  },
66
68
  "publishConfig": {
67
69
  "access": "public"
68
70
  },
69
- "gitHead": "cc40e90b2dc188debd134f25fe05b1ef5eb14ff2"
71
+ "gitHead": "d6b6fc199e367698d566f38ee3343b04a418c829"
70
72
  }
@@ -48,6 +48,12 @@ export interface ClarinetConfig {
48
48
  contracts: ClarinetContracts;
49
49
  }
50
50
 
51
+ export const CLARINET_SETTINGS = [
52
+ 'Devnet.toml',
53
+ 'Testnet.toml',
54
+ 'Mainnet.toml',
55
+ ];
56
+
51
57
  export async function getClarinetConfig(folder: string) {
52
58
  const baseConfigPath = resolve(folder, 'Clarinet.toml');
53
59
  const configContents = await readFile(baseConfigPath, { encoding: 'utf-8' });
@@ -41,7 +41,7 @@ export const jsTypeFromAbiType = (
41
41
  } else if (isClarityAbiResponse(val)) {
42
42
  const ok: any = jsTypeFromAbiType(val.response.ok);
43
43
  const err: any = jsTypeFromAbiType(val.response.error);
44
- return `ClarityTypes.Response<${ok}, ${err}>`;
44
+ return `Response<${ok}, ${err}>`;
45
45
  } else if (isClarityAbiOptional(val)) {
46
46
  const innerType = jsTypeFromAbiType(val.optional);
47
47
  return `${innerType} | null`;
@@ -69,7 +69,7 @@ export const jsTypeFromAbiType = (
69
69
  };
70
70
 
71
71
  // Check if it's a reserved word, and then camelCase
72
- function getArgName(name: string) {
72
+ export function getArgName(name: string) {
73
73
  const camel = toCamelCase(name);
74
74
  const prefix = check(camel, 6) ? '_' : '';
75
75
  return `${prefix}${camel}`;
@@ -115,7 +115,7 @@ export const ${varName}Info: Contract<${contractType}> = {
115
115
  export const generateTypesFile = (abi: ClarityAbi, contractName: string) => {
116
116
  const name = toCamelCase(contractName, true);
117
117
  const typings = makePureTypes(abi);
118
- const fileContents = `import { ClarityTypes, ContractCalls } from '@clarigen/core';
118
+ const fileContents = `import { Response, ContractCalls } from '@clarigen/core';
119
119
 
120
120
  // prettier-ignore
121
121
  export interface ${name}Contract {
@@ -0,0 +1,134 @@
1
+ import { toCamelCase } from '@clarigen/core';
2
+ import type { ConfigFile } from '../config';
3
+ import { getArgName, jsTypeFromAbiType } from './declaration';
4
+ import type { ContractMeta } from '../utils';
5
+ import { relative, resolve } from 'path';
6
+ import { readFile } from 'fs/promises';
7
+ import { inspect } from 'util';
8
+
9
+ export function generateContractMeta(contract: ContractMeta) {
10
+ const { abi } = contract;
11
+ const functionLines: string[] = [];
12
+ const { functions, variables, maps, ...rest } = abi;
13
+ functions.forEach((func) => {
14
+ let functionLine = `${toCamelCase(func.name)}: `;
15
+ const args = func.args.map((arg) => {
16
+ return `${getArgName(arg.name)}: ${jsTypeFromAbiType(arg.type, true)}`;
17
+ });
18
+ const argsTuple = `[${args.join(', ')}]`;
19
+ const funcDef = JSON.stringify(func);
20
+ functionLine += funcDef;
21
+ const retType = jsTypeFromAbiType(func.outputs.type);
22
+ functionLine += ` as TypedAbiFunction<${argsTuple}, ${retType}>`;
23
+ functionLines.push(functionLine);
24
+ });
25
+
26
+ const variableLines = contract.variables.map((v) => {
27
+ let varLine = `${toCamelCase(v.name)}: `;
28
+ const type = jsTypeFromAbiType(v.type);
29
+ const varJSON = inspect(v, false, null, false);
30
+ varLine += `${varJSON} as TypedAbiVariable<${type}>`;
31
+ return varLine;
32
+ });
33
+
34
+ const constants = contract.variables.filter((v) => v.access === 'constant');
35
+ const constantLines = constants.map((constant) => {
36
+ return `"${toCamelCase(constant.name)}": ${serialize(
37
+ constant.defaultValue
38
+ )}`;
39
+ });
40
+
41
+ const mapLines = maps.map((map) => {
42
+ let mapLine = `${toCamelCase(map.name)}: `;
43
+ const keyType = jsTypeFromAbiType(map.key);
44
+ const valType = jsTypeFromAbiType(map.value);
45
+ mapLine += JSON.stringify(map);
46
+ mapLine += ` as TypedAbiMap<${keyType}, ${valType}>`;
47
+ return mapLine;
48
+ });
49
+
50
+ const otherAbi = JSON.stringify(rest);
51
+
52
+ const contractFile = relative(process.cwd(), contract.contractFile);
53
+
54
+ return `{
55
+ ${serializeLines('functions', functionLines)}
56
+ ${serializeLines('variables', variableLines)}
57
+ ${serializeLines('maps', mapLines)}
58
+ ${serializeLines('constants', constantLines)}
59
+ ${otherAbi.slice(1, -1)},
60
+ contractName: '${contract.contractName}',
61
+ contractFile: '${contractFile}',
62
+ }`;
63
+ }
64
+
65
+ export async function generateSingleFile(
66
+ config: ConfigFile,
67
+ contracts: ContractMeta[]
68
+ ) {
69
+ const contractDefs = contracts.map((contract) => {
70
+ const meta = generateContractMeta(contract);
71
+ const keyName = toCamelCase(contract.contractName);
72
+ return `${keyName}: ${meta}`;
73
+ });
74
+
75
+ const types = await getSingleTypes();
76
+ const accounts = generateAccounts(config);
77
+
78
+ const file = `
79
+ ${types}
80
+
81
+ export const contracts = {
82
+ ${contractDefs.join(',\n')}
83
+ } as const;
84
+
85
+ ${accounts}
86
+ `;
87
+ return file;
88
+ }
89
+
90
+ function generateAccounts(config: ConfigFile) {
91
+ let accounts = '';
92
+ if ('accounts' in config) {
93
+ const accountLines = Object.keys(config.accounts).map((key) => {
94
+ const account = config.accounts[key];
95
+ return `"${key}": {
96
+ mnemonic: "${account.mnemonic}",
97
+ balance: ${account.balance.toString()}n,
98
+ address: "${account.address}",
99
+ },`;
100
+ });
101
+
102
+ accounts = `export const accounts = {
103
+ ${accountLines.join('\n ')}
104
+ } as const;`;
105
+ }
106
+ return accounts;
107
+ }
108
+
109
+ Uint8Array.prototype[inspect.custom] = function (this: Uint8Array) {
110
+ return `Uint8Array.from([${this.join(',')}])`;
111
+ };
112
+
113
+ export function serialize(obj: any) {
114
+ return inspect(obj, {
115
+ showHidden: false,
116
+ maxArrayLength: null,
117
+ maxStringLength: null,
118
+ depth: null,
119
+ colors: false,
120
+ });
121
+ }
122
+
123
+ function serializeLines(key: string, lines: string[]) {
124
+ return `"${key}": {
125
+ ${lines.join(',\n ')}
126
+ },`;
127
+ }
128
+
129
+ export async function getSingleTypes() {
130
+ // 🤔 weird stuff with tsup shims
131
+ const typesPath = resolve(__dirname, '../../dist/abi-types.ts.txt');
132
+ const typesFile = await readFile(typesPath, { encoding: 'utf-8' });
133
+ return typesFile;
134
+ }
@@ -0,0 +1,82 @@
1
+ import {
2
+ ClarityAbiType,
3
+ cvToValue,
4
+ AbiTypeTo,
5
+ ClarityAbi,
6
+ } from '@clarigen/core';
7
+ import { evalRaw, NativeClarityBinProvider } from '@clarigen/native-bin';
8
+ import { ClarityAbiVariable, hexToCV } from 'micro-stacks/clarity';
9
+ import type { ContractMeta } from '../utils';
10
+
11
+ // export interface TypedAbiVariable<T extends ClarityAbiType>
12
+ // extends ClarityAbiVariable {
13
+ // type: T;
14
+ // defaultValue: AbiTypeTo<T>;
15
+ // }
16
+ export type TypedAbiVariable<T> = ClarityAbiVariable & {
17
+ defaultValue: T;
18
+ };
19
+ // export type TypedAbiVariable<T> = T extends ClarityAbiVariable ?
20
+ // T['type'] extends ClarityAbiType ?
21
+ export type VariableType<T> = T extends ClarityAbiVariable ? T['type'] : never;
22
+
23
+ export async function getVariables({
24
+ abi,
25
+ contractIdentifier,
26
+ provider,
27
+ }: {
28
+ abi: ClarityAbi;
29
+ contractIdentifier: string;
30
+ provider: NativeClarityBinProvider;
31
+ }) {
32
+ const variableTransforms = abi.variables.map((variable) => {
33
+ return evalVariable({
34
+ variable,
35
+ provider,
36
+ contractIdentifier,
37
+ });
38
+ });
39
+ const variables = await Promise.all(variableTransforms);
40
+ return variables;
41
+ }
42
+
43
+ export async function evalVariable<T extends ClarityAbiVariable>({
44
+ contractIdentifier,
45
+ variable,
46
+ provider,
47
+ }: {
48
+ contractIdentifier: string;
49
+ variable: T;
50
+ provider: NativeClarityBinProvider;
51
+ }) {
52
+ const code = getEvalCode(variable);
53
+ const result = await evalRaw({
54
+ contractAddress: contractIdentifier,
55
+ code,
56
+ provider,
57
+ });
58
+ const resultCV = hexToCV(result.output_serialized);
59
+ const value = cvToValue(resultCV, true);
60
+ return {
61
+ ...variable,
62
+ defaultValue: value,
63
+ };
64
+ }
65
+
66
+ // export async function
67
+
68
+ function getEvalCode(variable: ClarityAbiVariable) {
69
+ const { access } = variable;
70
+ if (access === 'variable') {
71
+ return `(var-get ${variable.name})`;
72
+ }
73
+ return variable.name;
74
+ }
75
+
76
+ // export function serializeVariable(variable: TypedAbiVariable<any>) {
77
+ // const { defaultValue, ...rest } = variable;
78
+ // const lines = Object.keys(rest).map((key) => {
79
+ // return `"${key}": ${JSON.stringify(rest[key])}`;
80
+ // });
81
+ // const valueLine = typeof defaultValue === 'bigint' ? `${defaultValue.toString()}n` : JSON.stringify()
82
+ // }
package/src/utils.ts CHANGED
@@ -8,11 +8,26 @@ import {
8
8
  import {
9
9
  NativeClarityBinProvider,
10
10
  createClarityBin,
11
+ deployContract,
11
12
  } from '@clarigen/native-bin';
12
13
  import { resolve, relative, dirname } from 'path';
13
- import { mkdir, writeFile } from 'fs/promises';
14
+ import { mkdir } from 'fs/promises';
14
15
  import { getProjectConfig } from './config';
15
16
  import { generateDocsIndex, generateMarkdownDoc } from './docs';
17
+ import { ClarityAbi, Contract } from '@clarigen/core';
18
+ import { generateContractMeta, generateSingleFile } from './generate/single';
19
+ import { writeFile } from './writer';
20
+ import { getVariables, TypedAbiVariable } from './generate/vars';
21
+ import { ClarityAbiVariable } from 'micro-stacks/clarity';
22
+
23
+ export interface ContractMeta {
24
+ abi: ClarityAbi;
25
+ contractFile: string;
26
+ dirName: string;
27
+ contractName: string;
28
+ contractAddress: string;
29
+ variables: TypedAbiVariable<unknown>[];
30
+ }
16
31
 
17
32
  export const generateFilesForContract = async ({
18
33
  contractFile: _contractFile,
@@ -30,15 +45,21 @@ export const generateFilesForContract = async ({
30
45
  dirName?: string;
31
46
  contractName: string;
32
47
  docsPath?: string;
33
- }) => {
48
+ }): Promise<ContractMeta> => {
34
49
  const contractFile = resolve(process.cwd(), _contractFile);
50
+ const contractIdentifier = `${contractAddress}.${contractName}`;
35
51
 
36
- const abi = await generateInterface({
37
- contractFile,
52
+ const abi = await deployContract({
53
+ contractIdentifier,
54
+ contractFilePath: contractFile,
38
55
  provider,
39
- contractAddress,
40
- contractName,
41
56
  });
57
+ const variables = await getVariables({
58
+ abi,
59
+ contractIdentifier,
60
+ provider,
61
+ });
62
+
42
63
  const typesFile = generateTypesFile(abi, contractName);
43
64
  const indexFile = generateIndexFile({
44
65
  contractFile: relative(process.cwd(), contractFile),
@@ -63,6 +84,15 @@ export const generateFilesForContract = async ({
63
84
  await writeFile(resolve(outputPath, 'abi.ts'), abiFile);
64
85
  await writeFile(resolve(outputPath, 'index.ts'), indexFile);
65
86
  await writeFile(resolve(outputPath, 'types.ts'), typesFile);
87
+
88
+ return {
89
+ abi,
90
+ contractFile,
91
+ contractName,
92
+ dirName,
93
+ contractAddress,
94
+ variables,
95
+ };
66
96
  };
67
97
 
68
98
  export const generateProject = async (projectPath: string) => {
@@ -70,11 +100,12 @@ export const generateProject = async (projectPath: string) => {
70
100
  const { contractsDir, outputDir, contracts } = configFile;
71
101
  const outputFolder = resolve(projectPath, outputDir);
72
102
  const provider = await createClarityBin();
103
+ const metas: ContractMeta[] = [];
73
104
  // this needs to be serial
74
105
  for (const contract of contracts) {
75
106
  const contractFile = resolve(projectPath, contractsDir, contract.file);
76
107
  const dirName = dirname(contract.file);
77
- await generateFilesForContract({
108
+ const meta = await generateFilesForContract({
78
109
  contractFile,
79
110
  outputFolder: outputFolder,
80
111
  provider,
@@ -83,6 +114,7 @@ export const generateProject = async (projectPath: string) => {
83
114
  contractName: contract.name,
84
115
  docsPath: configFile.docs,
85
116
  });
117
+ metas.push(meta);
86
118
  }
87
119
 
88
120
  const indexFile = generateProjectIndexFile(configFile);
@@ -90,4 +122,8 @@ export const generateProject = async (projectPath: string) => {
90
122
 
91
123
  const indexPath = resolve(outputFolder, 'index.ts');
92
124
  await writeFile(indexPath, indexFile);
125
+
126
+ const singleFile = await generateSingleFile(configFile, metas);
127
+ const singlePath = resolve(outputFolder, 'single.ts');
128
+ await writeFile(singlePath, singleFile);
93
129
  };
package/src/writer.ts ADDED
@@ -0,0 +1,39 @@
1
+ // Utilities for writing and formatting files
2
+ import { writeFile as _writeFile } from 'fs/promises';
3
+ import { basename } from 'path';
4
+ import { resolveConfig, format, Options } from 'prettier';
5
+
6
+ const defaultPrettierConfig: Options = {
7
+ printWidth: 80,
8
+ semi: true,
9
+ singleQuote: true,
10
+ trailingComma: 'es5',
11
+ };
12
+
13
+ export async function resolvePrettierConfig(): Promise<Options> {
14
+ try {
15
+ const local = await resolveConfig(process.cwd());
16
+ if (local) return local;
17
+ } catch (error) {}
18
+ return defaultPrettierConfig;
19
+ }
20
+
21
+ export async function formatFile(contents: string, path: string) {
22
+ try {
23
+ const fileName = basename(path);
24
+ const config = await resolvePrettierConfig();
25
+ const formatted = format(contents, {
26
+ ...config,
27
+ filepath: fileName,
28
+ });
29
+ return formatted;
30
+ } catch (error) {
31
+ // handle formatting error
32
+ }
33
+ return contents;
34
+ }
35
+
36
+ export async function writeFile(path: string, contents: string) {
37
+ const formatted = await formatFile(contents, path);
38
+ await _writeFile(path, formatted);
39
+ }
@@ -1,16 +0,0 @@
1
- import * as _oclif_parser_lib_flags from '@oclif/parser/lib/flags';
2
- import { Command } from '@oclif/command';
3
-
4
- declare class Generate extends Command {
5
- static description: string;
6
- static strict: boolean;
7
- static hidden: boolean;
8
- static flags: {
9
- help: _oclif_parser_lib_flags.IBooleanFlag<void>;
10
- watch: _oclif_parser_lib_flags.IBooleanFlag<boolean>;
11
- };
12
- static args: any[];
13
- run(): Promise<void>;
14
- }
15
-
16
- export { Generate };
@@ -1,78 +0,0 @@
1
- var rt=Object.defineProperty,nt=Object.defineProperties;var et=Object.getOwnPropertyDescriptors;var w=Object.getOwnPropertySymbols;var k=Object.prototype.hasOwnProperty,N=Object.prototype.propertyIsEnumerable;var j=(t,n,r)=>n in t?rt(t,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[n]=r,$=(t,n)=>{for(var r in n||(n={}))k.call(n,r)&&j(t,r,n[r]);if(w)for(var r of w(n))N.call(n,r)&&j(t,r,n[r]);return t},h=(t,n)=>nt(t,et(n));var ot=(t=>typeof require!="undefined"?require:typeof Proxy!="undefined"?new Proxy(t,{get:(n,r)=>(typeof require!="undefined"?require:n)[r]}):t)(function(t){if(typeof require!="undefined")return require.apply(this,arguments);throw new Error('Dynamic require of "'+t+'" is not supported')});var D=(t,n)=>{var r={};for(var e in t)k.call(t,e)&&n.indexOf(e)<0&&(r[e]=t[e]);if(t!=null&&w)for(var e of w(t))n.indexOf(e)<0&&N.call(t,e)&&(r[e]=t[e]);return r};import{Command as Wt,flags as Y}from"@oclif/command";import{hasStdErr as kt}from"@clarigen/native-bin";import{toCamelCase as x}from"@clarigen/core";import{dirname as Nt,join as Dt}from"path";import{run as Cr}from"@oclif/command";import{resolve as R,join as gt,relative as ut}from"path";import{readFile as mt,access as Ct}from"fs/promises";import{constants as dt}from"fs";import{parse as v}from"@ltd/j-toml";import{resolve as S}from"path";import{readFile as O}from"fs/promises";import{generateWallet as it,getStxAddressFromAccount as st}from"micro-stacks/wallet-sdk";import{array as ct}from"toposort";import{StacksNetworkVersion as at}from"micro-stacks/crypto";async function lt(t){let n=S(t,"settings","Devnet.toml"),r=await O(n,{encoding:"utf-8"});return v(r,1,`
2
- `,!0,{longer:!0})}async function ft(t){let n=S(t,"Clarinet.toml"),r=await O(n,{encoding:"utf-8"});return v(r,1,`
3
- `,!0)}async function _(t,n){let r=await ft(t),e=n.deployer.address;return pt(r.contracts).map(c=>({file:r.contracts[c].path.replace(/^contracts\//,""),address:e,name:c}))}function pt(t){let n=[],r=[];return Object.entries(t).forEach(([o,i])=>{r.push(o),i.depends_on.forEach(c=>n.push([o,c]))}),ct(r,n).reverse()}async function B(t){let n=await lt(t),r=await Promise.all(Object.entries(n.accounts).map(async([o,i])=>{let c=await it(i.mnemonic,"password"),[s]=c.accounts,a=st(s,at.testnetP2PKH);return[o,h($({},i),{address:a})]}));return Object.fromEntries(r)}var L={outputDir:"src/clarigen",clarinet:"."};function yt(t){return R(t,"clarigen.config.json")}async function $t(t){try{return await Ct(t,dt.R_OK),!0}catch{return!1}}async function xt(t){let n=yt(t);if(await $t(n)){let e=await mt(n,{encoding:"utf-8"}),o=JSON.parse(e);return $($({},L),o)}return L}async function b(t){let n=await xt(t),r=R(t,n.clarinet||"."),e=await B(r),o=await _(r,e),i=ut(process.cwd(),gt(n.clarinet,"contracts"));return h($({},n),{contracts:o,contractsDir:i,accounts:e,clarinet:n.clarinet||"."})}import{isClarityAbiBuffer as wt,isClarityAbiList as ht,isClarityAbiOptional as bt,isClarityAbiPrimitive as Ft,isClarityAbiResponse as J,isClarityAbiStringAscii as At,isClarityAbiStringUtf8 as Pt,isClarityAbiTuple as Tt}from"micro-stacks/transactions";import{toCamelCase as P}from"@clarigen/core";import{check as Et}from"reserved-words";var f=(t,n=!1)=>{if(Ft(t)){if(t==="uint128")return n?"number | bigint":"bigint";if(t==="int128")return n?"number | bigint":"bigint";if(t==="bool")return"boolean";if(t==="principal")return"string";if(t==="none")return"null";if(t==="trait_reference")return"string";throw new Error(`Unexpected Clarity ABI type primitive: ${JSON.stringify(t)}`)}else{if(wt(t))return"Uint8Array";if(J(t)){let r=f(t.response.ok),e=f(t.response.error);return`ClarityTypes.Response<${r}, ${e}>`}else{if(bt(t))return`${f(t.optional)} | null`;if(Tt(t)){let r=[];return t.tuple.forEach(({name:e,type:o})=>{let i=f(o);r.push(`"${e}": ${i}`)}),`{
4
- ${r.join(`;
5
- `)}
6
- }`}else{if(ht(t))return`${f(t.list.type)}[]`;if(At(t))return"string";if(Pt(t))return"string";if(t==="trait_reference")return"string";throw new Error(`Unexpected Clarity ABI type: ${JSON.stringify(t)}`)}}}};function It(t){let n=P(t);return`${Et(n,6)?"_":""}${n}`}var jt={public:"Public",read_only:"ReadOnly",private:"Private"};function M(t){let n="";return t.functions.forEach((r,e)=>{let o=`${P(r.name)}: `;if(o+=`(${r.args.map(s=>`${It(s.name)}: ${f(s.type,!0)}`).join(", ")}) => `,o+=`ContractCalls.${jt[r.access]}<`,r.access==="public"){let{type:s}=r.outputs;if(!J(s))throw new Error("Expected response type for public function");let a=f(s.response.ok),l=f(s.response.error);o+=`${a}, ${l}>;`}else o+=`${f(r.outputs.type)}>;`;n+=`${e===0?"":`
7
- `} ${o}`}),t.maps.forEach(r=>{let e=`${P(r.name)}: `,o=f(r.key,!0),i=`key: ${o}`,c=f(r.value);e+=`(${i}) => ContractCalls.Map<${o}, ${c}>;`,n+=`
8
- ${e}`}),n}var U=async({provider:t,contractFile:n,contractAddress:r,contractName:e})=>{let o=await t.runCommand(["launch",`${r}.${e}`,n,t.dbFilePath,"--output_analysis","--costs","--assets"]);if(kt(o.stderr))throw new Error(`Error on ${n}:
9
- ${o.stderr}
10
- `);let i=JSON.parse(o.stdout);if(i.error){let{initialization:s}=i.error;if(s!=null&&s.includes(`
11
- Near:
12
- `)){let[a,l]=s.split(`
13
- Near:
14
- `),p="",g=/start_line: (\d+),/.exec(l);throw g&&(p=g[1]),new Error(`Error on ${n}:
15
- ${a}
16
- ${p?`Near line ${p}`:""}
17
- Raw trace:
18
- ${l}
19
- `)}throw new Error(`Error on ${n}:
20
- ${JSON.stringify(i.error,null,2)}
21
- `)}return i.analysis},W=({contractName:t,abi:n})=>{let r=x(t,!0),s=n,{clarity_version:e}=s,o=D(s,["clarity_version"]),i=JSON.stringify(o,null,2);return`import { ClarityAbi } from '@clarigen/core';
22
-
23
- // prettier-ignore
24
- export const ${r}Interface: ClarityAbi = ${i};
25
- `},V=({contractFile:t,contractAddress:n,contractName:r})=>{let e=x(r,!0),o=x(r),i=`${e}Contract`,c=`${e}Interface`;return`import { pureProxy, Contract } from '@clarigen/core';
26
- import type { ${i} } from './types';
27
- import { ${c} } from './abi';
28
- export type { ${i} } from './types';
29
-
30
- export function ${o}Contract(contractAddress: string, contractName: string) {
31
- return pureProxy<${i}>({
32
- abi: ${c},
33
- contractAddress,
34
- contractName,
35
- });
36
- }
37
-
38
- export const ${o}Info: Contract<${i}> = {
39
- contract: ${o}Contract,
40
- address: '${n}',
41
- contractFile: '${t}',
42
- name: '${r}',
43
- abi: ${c},
44
- };
45
- `},K=(t,n)=>{let r=x(n,!0),e=M(t);return`import { ClarityTypes, ContractCalls } from '@clarigen/core';
46
-
47
- // prettier-ignore
48
- export interface ${r}Contract {
49
- ${e}
50
- }
51
- `},q=t=>{let n=["import type { ContractInstances } from '@clarigen/core';"],r=[],e=[],o="";"accounts"in t&&(o=`
52
-
53
- // prettier-ignore
54
- export const accounts = {
55
- ${Object.keys(t.accounts).map(a=>{let l=t.accounts[a];return`"${a}": {
56
- mnemonic: "${l.mnemonic}",
57
- balance: ${l.balance.toString()}n,
58
- address: "${l.address}",
59
- },`}).join(`
60
- `)}
61
- };`),t.contracts.forEach(s=>{let a=s.name,l=x(a),p=`${l}Info`,y=`${x(a,!0)}Contract`,g=Nt(s.file),I=`'./${Dt(g||".",a)}'`,z=`import { ${p} } from ${I};`;n.push(z);let G=`export type { ${y} } from ${I};`;r.push(G);let tt=`${l}: ${p},`;e.push(tt)});let i=`
62
- export type Contracts = ContractInstances<typeof contracts>;
63
- `;return`${n.join(`
64
- `)}
65
- ${r.join(`
66
- `)}
67
- ${i}
68
- export const contracts = {
69
- ${e.join(`
70
- `)}
71
- };${o}
72
- `};import{createClarityBin as Lt}from"@clarigen/native-bin";import{resolve as u,relative as Rt,dirname as Jt}from"path";import{mkdir as Mt,writeFile as F}from"fs/promises";import{createContractDocInfo as vt,generateMarkdown as St}from"@clarigen/claridocs";import{mkdir as Ot,readFile as _t,writeFile as H}from"fs/promises";import{relative as Bt,resolve as T}from"path";async function Q({contractFile:t,contractName:n,docsPath:r,abi:e,dirName:o}){let i=await _t(t,{encoding:"utf-8"}),c=vt({contractSrc:i,abi:e}),s=T(process.cwd(),r,o||"."),a=T(s,`${n}.md`),l=St({contract:c,contractFile:Bt(s,t),contractName:n,abi:e});await Ot(s,{recursive:!0}),await H(a,l)}async function X(t){if(!t.docs)return;let r=`# Contracts
73
-
74
- ${t.contracts.map(o=>{let i=o.file.replace(".clar",".md");return`- [\`${o.name}\`](${i})`}).join(`
75
- `)}
76
- `,e=T(process.cwd(),t.docs,"README.md");await H(e,r)}var Ut=async({contractFile:t,outputFolder:n,provider:r,contractAddress:e,dirName:o,contractName:i,docsPath:c})=>{let s=u(process.cwd(),t),a=await U({contractFile:s,provider:r,contractAddress:e,contractName:i}),l=K(a,i),p=V({contractFile:Rt(process.cwd(),s),contractAddress:e,contractName:i}),y=W({contractName:i,abi:a});typeof c<"u"&&await Q({contractFile:s,contractName:i,abi:a,docsPath:c,dirName:o});let g=u(n,o||".",i);await Mt(g,{recursive:!0}),await F(u(g,"abi.ts"),y),await F(u(g,"index.ts"),p),await F(u(g,"types.ts"),l)},A=async t=>{let n=await b(t),{contractsDir:r,outputDir:e,contracts:o}=n,i=u(t,e),c=await Lt();for(let l of o){let p=u(t,r,l.file),y=Jt(l.file);await Ut({contractFile:p,outputFolder:i,provider:c,contractAddress:l.address,dirName:y,contractName:l.name,docsPath:n.docs})}let s=q(n);await X(n);let a=u(i,"index.ts");await F(a,s)};import{watch as Vt}from"chokidar";import{basename as Kt}from"path";import{red as qt,green as Z}from"chalk";var Ht=ot("ora"),E=class extends Wt{async run(){let{flags:n}=this.parse(E),r=process.cwd();if(n.watch){let e=Ht("Generating files").start(),{contractsDir:o}=await b(r),i=Vt([o],{cwd:r});try{await A(r),e.succeed("Finished generating files. Watching for changes.")}catch(c){e.fail(`Error generating files.
77
- ${c.message}`)}i.on("change",async c=>{let s=Kt(c);e.clear(),e.start(`Change detected for ${Z(s)}, generating.`);try{await A(r),e.succeed(`Finished generating files for ${Z(s)}. Watching for changes.`)}catch(a){let l=a.message;e.fail(`Error after saving ${qt(s)}.
78
- ${l}`)}}),process.on("SIGINT",async()=>{await i.close(),process.exit()})}else await A(r)}},d=E;d.description="Generate project files",d.strict=!0,d.hidden=!1,d.flags={help:Y.help({char:"h"}),watch:Y.boolean({char:"w",description:"Watch for changes to your contracts"})},d.args=[];export{d as Generate};
package/dist/index.d.ts DELETED
@@ -1,63 +0,0 @@
1
- export { run } from '@oclif/command';
2
- import { ClarityAbiType } from 'micro-stacks/clarity';
3
- import { ClarityAbi } from '@clarigen/core';
4
- import { NativeClarityBinProvider } from '@clarigen/native-bin';
5
- export { Generate } from './commands/index.js';
6
- import '@oclif/parser/lib/flags';
7
-
8
- interface ClarinetConfigAccount {
9
- mnemonic: string;
10
- balance: bigint;
11
- }
12
- interface ClarinetAccount extends ClarinetConfigAccount {
13
- address: string;
14
- }
15
- interface ClarinetAccounts {
16
- deployer: ClarinetAccount;
17
- [name: string]: ClarinetAccount;
18
- }
19
-
20
- interface ConfigContract {
21
- address: string;
22
- file: string;
23
- name: string;
24
- }
25
- interface ConfigFileContents {
26
- outputDir: string;
27
- clarinet: string;
28
- docs?: string;
29
- }
30
- interface ConfigFile extends ConfigFileContents {
31
- contractsDir: string;
32
- contracts: ConfigContract[];
33
- accounts: ClarinetAccounts;
34
- clarinet: string;
35
- }
36
- declare const defaultConfigFile: ConfigFileContents;
37
- declare function configFilePath(rootPath: string): string;
38
- declare function configFileExists(configPath: string): Promise<boolean>;
39
- declare function getConfigFile(rootPath: string): Promise<ConfigFileContents>;
40
- declare function getProjectConfig(rootPath: string): Promise<ConfigFile>;
41
-
42
- declare const jsTypeFromAbiType: (val: ClarityAbiType, isArgument?: boolean) => string;
43
- declare function makePureTypes(abi: ClarityAbi): string;
44
-
45
- declare const generateInterface: ({ provider, contractFile, contractAddress, contractName, }: {
46
- contractFile: string;
47
- provider: NativeClarityBinProvider;
48
- contractAddress: string;
49
- contractName: string;
50
- }) => Promise<ClarityAbi>;
51
- declare const generateInterfaceFile: ({ contractName, abi, }: {
52
- contractName: string;
53
- abi: ClarityAbi;
54
- }) => string;
55
- declare const generateIndexFile: ({ contractFile, contractAddress, contractName, }: {
56
- contractFile: string;
57
- contractAddress: string;
58
- contractName: string;
59
- }) => string;
60
- declare const generateTypesFile: (abi: ClarityAbi, contractName: string) => string;
61
- declare const generateProjectIndexFile: (config: ConfigFile) => string;
62
-
63
- export { ConfigContract, ConfigFile, ConfigFileContents, configFileExists, configFilePath, defaultConfigFile, generateIndexFile, generateInterface, generateInterfaceFile, generateProjectIndexFile, generateTypesFile, getConfigFile, getProjectConfig, jsTypeFromAbiType, makePureTypes };