@clarigen/cli 1.0.0-next.24 → 1.0.0-next.25

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.
@@ -58,35 +58,118 @@ var import_command2 = require("@oclif/command");
58
58
 
59
59
  // src/generate/files.ts
60
60
  var import_core2 = require("@clarigen/core");
61
- var import_path3 = require("path");
61
+ var import_path5 = require("path");
62
62
 
63
63
  // src/index.ts
64
64
  var import_command = require("@oclif/command");
65
65
 
66
66
  // src/config.ts
67
- var import_path2 = require("path");
68
- var import_promises2 = require("fs/promises");
69
- var import_fs = require("fs");
67
+ var import_path4 = require("path");
68
+ var import_promises4 = require("fs/promises");
69
+ var import_fs2 = require("fs");
70
70
 
71
71
  // src/clarinet-config.ts
72
72
  var import_toml = require("@iarna/toml");
73
- var import_path = require("path");
74
- var import_promises = require("fs/promises");
73
+ var import_path3 = require("path");
74
+ var import_promises3 = require("fs/promises");
75
75
  var import_wallet_sdk = require("micro-stacks/wallet-sdk");
76
76
  var import_toposort = require("toposort");
77
77
  var import_crypto = require("micro-stacks/crypto");
78
+
79
+ // src/generate/deployment.ts
80
+ var import_js_yaml = require("js-yaml");
81
+ var import_promises2 = require("fs/promises");
82
+ var import_path2 = require("path");
83
+ var import_fs = require("fs");
84
+
85
+ // src/writer.ts
86
+ var import_promises = require("fs/promises");
87
+ var import_path = require("path");
88
+ var import_prettier = require("prettier");
89
+ var defaultPrettierConfig = {
90
+ printWidth: 80,
91
+ semi: true,
92
+ singleQuote: true,
93
+ trailingComma: "es5"
94
+ };
95
+ async function resolvePrettierConfig() {
96
+ try {
97
+ const local = await (0, import_prettier.resolveConfig)(process.cwd());
98
+ if (local)
99
+ return local;
100
+ } catch (error) {
101
+ }
102
+ return defaultPrettierConfig;
103
+ }
104
+ async function formatFile(contents, path) {
105
+ try {
106
+ const fileName = (0, import_path.basename)(path);
107
+ const config = await resolvePrettierConfig();
108
+ const formatted = (0, import_prettier.format)(contents, __spreadProps(__spreadValues({}, config), {
109
+ filepath: fileName
110
+ }));
111
+ return formatted;
112
+ } catch (error) {
113
+ }
114
+ return contents;
115
+ }
116
+ async function writeFile(path, contents) {
117
+ const formatted = await formatFile(contents, path);
118
+ await (0, import_promises.writeFile)(path, formatted);
119
+ }
120
+
121
+ // src/generate/deployment.ts
122
+ async function parseDeployment(path) {
123
+ const contents = await (0, import_promises2.readFile)(path, { encoding: "utf-8" });
124
+ const parsed = (0, import_js_yaml.load)(contents);
125
+ return parsed;
126
+ }
127
+ async function generateDeployment(network, config) {
128
+ const file = `default.${network}-plan.yaml`;
129
+ const deploymentPath = (0, import_path2.resolve)(process.cwd(), config.clarinet, "deployments", file);
130
+ if ((0, import_fs.existsSync)(deploymentPath)) {
131
+ const plan = await parseDeployment(deploymentPath);
132
+ const varName = `${network}Deployment`;
133
+ const contents = `export const ${varName} = ${JSON.stringify(plan)} as const;
134
+ `;
135
+ const outputFile = (0, import_path2.resolve)(config.outputDir, "deployments", `${network}.ts`);
136
+ await writeFile(outputFile, contents);
137
+ }
138
+ }
139
+ async function generateDeployments(config) {
140
+ const networks = ["devnet", "simnet", "testnet", "mainnet"];
141
+ const folder = (0, import_path2.resolve)(process.cwd(), config.outputDir, "deployments");
142
+ await (0, import_promises2.mkdir)(folder, { recursive: true });
143
+ const generates = networks.map((n) => generateDeployment(n, config));
144
+ await Promise.all(generates);
145
+ }
146
+
147
+ // src/clarinet-config.ts
78
148
  async function getClarinetDevConfig(folder) {
79
- const baseConfigPath = (0, import_path.resolve)(folder, "settings", "Devnet.toml");
80
- const configContents = await (0, import_promises.readFile)(baseConfigPath, { encoding: "utf-8" });
149
+ const baseConfigPath = (0, import_path3.resolve)(folder, "settings", "Devnet.toml");
150
+ const configContents = await (0, import_promises3.readFile)(baseConfigPath, { encoding: "utf-8" });
81
151
  const config = (0, import_toml.parse)(configContents);
82
152
  return config;
83
153
  }
84
154
  async function getClarinetConfig(folder) {
85
- const baseConfigPath = (0, import_path.resolve)(folder, "Clarinet.toml");
86
- const configContents = await (0, import_promises.readFile)(baseConfigPath, { encoding: "utf-8" });
155
+ const baseConfigPath = (0, import_path3.resolve)(folder, "Clarinet.toml");
156
+ const configContents = await (0, import_promises3.readFile)(baseConfigPath, { encoding: "utf-8" });
87
157
  const config = (0, import_toml.parse)(configContents);
88
158
  return config;
89
159
  }
160
+ async function getContractsFromDeployment(clarinetPath) {
161
+ const simnetPath = (0, import_path3.resolve)(clarinetPath || process.cwd(), "deployments/default.simnet-plan.yaml");
162
+ const deployment = await parseDeployment(simnetPath);
163
+ const txs = deployment.plan.batches[0].transactions;
164
+ return txs.map((_tx) => {
165
+ const tx = _tx["emulated-contract-publish"];
166
+ return {
167
+ file: tx.path,
168
+ name: tx["contract-name"],
169
+ address: tx["emulated-sender"]
170
+ };
171
+ });
172
+ }
90
173
  function getContractsFromClarinet(clarinetConfig, accounts) {
91
174
  const deployerAddress = accounts.deployer.address;
92
175
  const sortedContracts = sortClarinetContracts(clarinetConfig.contracts);
@@ -135,11 +218,11 @@ var defaultConfigFile = {
135
218
  clarinet: "."
136
219
  };
137
220
  function configFilePath(rootPath) {
138
- return (0, import_path2.resolve)(rootPath, "clarigen.config.json");
221
+ return (0, import_path4.resolve)(rootPath, "clarigen.config.json");
139
222
  }
140
223
  async function configFileExists(configPath) {
141
224
  try {
142
- await (0, import_promises2.access)(configPath, import_fs.constants.R_OK);
225
+ await (0, import_promises4.access)(configPath, import_fs2.constants.R_OK);
143
226
  return true;
144
227
  } catch (error) {
145
228
  return false;
@@ -149,7 +232,7 @@ async function getConfigFile(rootPath) {
149
232
  const fullPath = configFilePath(rootPath);
150
233
  const exists = await configFileExists(fullPath);
151
234
  if (exists) {
152
- const configContents = await (0, import_promises2.readFile)(fullPath, { encoding: "utf-8" });
235
+ const configContents = await (0, import_promises4.readFile)(fullPath, { encoding: "utf-8" });
153
236
  const configFile = JSON.parse(configContents);
154
237
  return __spreadValues(__spreadValues({}, defaultConfigFile), configFile);
155
238
  }
@@ -158,11 +241,16 @@ async function getConfigFile(rootPath) {
158
241
  async function getProjectConfig(rootPath) {
159
242
  var _a, _b;
160
243
  const configFile = await getConfigFile(rootPath);
161
- const clarinetPath = (0, import_path2.resolve)(rootPath, configFile.clarinet);
244
+ const clarinetPath = (0, import_path4.resolve)(rootPath, configFile.clarinet);
162
245
  const clarinet = await getClarinetConfig(clarinetPath);
163
246
  const accounts = await getClarinetAccounts(clarinetPath);
164
- const contracts = getContractsFromClarinet(clarinet, accounts);
165
- const contractsDir = (0, import_path2.relative)(process.cwd(), (0, import_path2.join)(configFile.clarinet, "contracts"));
247
+ let contracts;
248
+ try {
249
+ contracts = await getContractsFromDeployment(clarinetPath);
250
+ } catch (error) {
251
+ contracts = getContractsFromClarinet(clarinet, accounts);
252
+ }
253
+ const contractsDir = (0, import_path4.relative)(process.cwd(), (0, import_path4.join)(configFile.clarinet, "contracts"));
166
254
  return __spreadProps(__spreadValues({}, configFile), {
167
255
  outputDir: ((_a = clarinet.clarigen) == null ? void 0 : _a.output_dir) || configFile.outputDir,
168
256
  docs: ((_b = clarinet.clarigen) == null ? void 0 : _b.docs) || configFile.docs,
@@ -361,8 +449,8 @@ export const accounts = {
361
449
  const contractVar = (0, import_core2.toCamelCase)(contractName);
362
450
  const contractInfo = `${contractVar}Info`;
363
451
  const contractInterface = `${(0, import_core2.toCamelCase)(contractName, true)}Contract`;
364
- const dirName = (0, import_path3.dirname)(contract.file);
365
- const importPath = `'./${(0, import_path3.join)(dirName || ".", contractName)}'`;
452
+ const dirName = (0, import_path5.dirname)(contract.file);
453
+ const importPath = `'./${contractName}'`;
366
454
  const _import = `import { ${contractInfo} } from ${importPath};`;
367
455
  imports.push(_import);
368
456
  const _export = `export type { ${contractInterface} } from ${importPath};`;
@@ -385,13 +473,13 @@ export const contracts = {
385
473
 
386
474
  // src/utils.ts
387
475
  var import_native_bin2 = require("@clarigen/native-bin");
388
- var import_path8 = require("path");
389
- var import_promises7 = require("fs/promises");
476
+ var import_path9 = require("path");
477
+ var import_promises8 = require("fs/promises");
390
478
 
391
479
  // src/docs.ts
392
480
  var import_claridocs = require("@clarigen/claridocs");
393
- var import_promises3 = require("fs/promises");
394
- var import_path4 = require("path");
481
+ var import_promises5 = require("fs/promises");
482
+ var import_path6 = require("path");
395
483
  async function generateMarkdownDoc({
396
484
  contractFile,
397
485
  contractName,
@@ -399,18 +487,18 @@ async function generateMarkdownDoc({
399
487
  abi,
400
488
  dirName
401
489
  }) {
402
- const contractSrc = await (0, import_promises3.readFile)(contractFile, { encoding: "utf-8" });
490
+ const contractSrc = await (0, import_promises5.readFile)(contractFile, { encoding: "utf-8" });
403
491
  const docs = (0, import_claridocs.createContractDocInfo)({ contractSrc, abi });
404
- const folder = (0, import_path4.resolve)(process.cwd(), docsPath, dirName || ".");
405
- const filePath = (0, import_path4.resolve)(folder, `${contractName}.md`);
492
+ const folder = (0, import_path6.resolve)(process.cwd(), docsPath, dirName || ".");
493
+ const filePath = (0, import_path6.resolve)(folder, `${contractName}.md`);
406
494
  const md = (0, import_claridocs.generateMarkdown)({
407
495
  contract: docs,
408
- contractFile: (0, import_path4.relative)(folder, contractFile),
496
+ contractFile: (0, import_path6.relative)(folder, contractFile),
409
497
  contractName,
410
498
  abi
411
499
  });
412
- await (0, import_promises3.mkdir)(folder, { recursive: true });
413
- await (0, import_promises3.writeFile)(filePath, md);
500
+ await (0, import_promises5.mkdir)(folder, { recursive: true });
501
+ await (0, import_promises5.writeFile)(filePath, md);
414
502
  }
415
503
  async function generateDocsIndex(configFile) {
416
504
  if (!configFile.docs)
@@ -423,14 +511,14 @@ async function generateDocsIndex(configFile) {
423
511
 
424
512
  ${contractLines.join("\n")}
425
513
  `;
426
- const filepath = (0, import_path4.resolve)(process.cwd(), configFile.docs, "README.md");
427
- await (0, import_promises3.writeFile)(filepath, fileContents);
514
+ const filepath = (0, import_path6.resolve)(process.cwd(), configFile.docs, "README.md");
515
+ await (0, import_promises5.writeFile)(filepath, fileContents);
428
516
  }
429
517
 
430
518
  // src/generate/single.ts
431
519
  var import_core3 = require("@clarigen/core");
432
- var import_path5 = require("path");
433
- var import_promises4 = require("fs/promises");
520
+ var import_path7 = require("path");
521
+ var import_promises6 = require("fs/promises");
434
522
  var import_util = require("util");
435
523
  function generateContractMeta(contract) {
436
524
  const { abi } = contract;
@@ -468,7 +556,7 @@ function generateContractMeta(contract) {
468
556
  return mapLine;
469
557
  });
470
558
  const otherAbi = JSON.stringify(rest);
471
- const contractFile = (0, import_path5.relative)(process.cwd(), contract.contractFile);
559
+ const contractFile = (0, import_path7.relative)(process.cwd(), contract.contractFile);
472
560
  return `{
473
561
  ${serializeLines("functions", functionLines)}
474
562
  ${serializeLines("variables", variableLines)}
@@ -533,143 +621,48 @@ function serializeLines(key, lines) {
533
621
  },`;
534
622
  }
535
623
  async function getSingleTypes() {
536
- const typesPath = (0, import_path5.resolve)(__dirname, "../../dist/abi-types.ts.txt");
537
- const typesFile = await (0, import_promises4.readFile)(typesPath, { encoding: "utf-8" });
624
+ const typesPath = (0, import_path7.resolve)(__dirname, "../../dist/abi-types.ts.txt");
625
+ const typesFile = await (0, import_promises6.readFile)(typesPath, { encoding: "utf-8" });
538
626
  return typesFile;
539
627
  }
540
628
 
541
- // src/writer.ts
542
- var import_promises5 = require("fs/promises");
543
- var import_path6 = require("path");
544
- var import_prettier = require("prettier");
545
- var defaultPrettierConfig = {
546
- printWidth: 80,
547
- semi: true,
548
- singleQuote: true,
549
- trailingComma: "es5"
550
- };
551
- async function resolvePrettierConfig() {
552
- try {
553
- const local = await (0, import_prettier.resolveConfig)(process.cwd());
554
- if (local)
555
- return local;
556
- } catch (error) {
557
- }
558
- return defaultPrettierConfig;
559
- }
560
- async function formatFile(contents, path) {
561
- try {
562
- const fileName = (0, import_path6.basename)(path);
563
- const config = await resolvePrettierConfig();
564
- const formatted = (0, import_prettier.format)(contents, __spreadProps(__spreadValues({}, config), {
565
- filepath: fileName
566
- }));
567
- return formatted;
568
- } catch (error) {
569
- }
570
- return contents;
571
- }
572
- async function writeFile2(path, contents) {
573
- const formatted = await formatFile(contents, path);
574
- await (0, import_promises5.writeFile)(path, formatted);
575
- }
576
-
577
629
  // src/generate/vars.ts
578
630
  var import_core4 = require("@clarigen/core");
579
631
  var import_native_bin = require("@clarigen/native-bin");
580
632
  var import_clarity = require("micro-stacks/clarity");
581
- async function getVariables({
582
- abi,
583
- contractIdentifier,
584
- provider
585
- }) {
586
- const variableTransforms = abi.variables.map((variable) => {
587
- return evalVariable({
588
- variable,
589
- provider,
590
- contractIdentifier
591
- });
592
- });
593
- const variables = await Promise.all(variableTransforms);
594
- return variables;
595
- }
596
- async function evalVariable({
597
- contractIdentifier,
598
- variable,
599
- provider
600
- }) {
601
- const code = getEvalCode(variable);
602
- const result = await (0, import_native_bin.evalRaw)({
603
- contractAddress: contractIdentifier,
604
- code,
605
- provider
606
- });
607
- const resultCV = (0, import_clarity.hexToCV)(result.output_serialized);
608
- const value = (0, import_core4.cvToValue)(resultCV, true);
609
- return __spreadProps(__spreadValues({}, variable), {
610
- defaultValue: value
611
- });
612
- }
613
- function getEvalCode(variable) {
614
- const { access: access2 } = variable;
615
- if (access2 === "variable") {
616
- return `(var-get ${variable.name})`;
617
- }
618
- return variable.name;
619
- }
620
633
 
621
- // src/generate/deployment.ts
622
- var import_js_yaml = require("js-yaml");
623
- var import_promises6 = require("fs/promises");
624
- var import_path7 = require("path");
625
- var import_fs2 = require("fs");
626
- async function parseDeployment(path) {
627
- const contents = await (0, import_promises6.readFile)(path, { encoding: "utf-8" });
628
- const parsed = (0, import_js_yaml.load)(contents);
629
- return parsed;
630
- }
631
- async function generateDeployment(network, config) {
632
- const file = `default.${network}-plan.yaml`;
633
- const deploymentPath = (0, import_path7.resolve)(process.cwd(), config.clarinet, "deployments", file);
634
- if ((0, import_fs2.existsSync)(deploymentPath)) {
635
- const plan = await parseDeployment(deploymentPath);
636
- const varName = `${network}Deployment`;
637
- const contents = `export const ${varName} = ${JSON.stringify(plan)} as const;
638
- `;
639
- const outputFile = (0, import_path7.resolve)(config.outputDir, "deployments", `${network}.ts`);
640
- await writeFile2(outputFile, contents);
634
+ // src/deno-run.ts
635
+ var import_child_process = require("child_process");
636
+ var import_util2 = require("util");
637
+ var exec = (0, import_util2.promisify)(import_child_process.exec);
638
+ async function getClarinetSession(cwd) {
639
+ const scriptPath = "https://raw.githubusercontent.com/mechanismHQ/clarigen-deno/main/src/cli/print.ts";
640
+ const command = `clarinet run ${scriptPath}`;
641
+ try {
642
+ const result = await exec(command, { cwd });
643
+ const sessionJSON = result.stdout.split("\n")[1];
644
+ const session = JSON.parse(sessionJSON);
645
+ return session;
646
+ } catch (error) {
647
+ console.error(`Error getting clarinet session`);
648
+ throw error;
641
649
  }
642
650
  }
643
- async function generateDeployments(config) {
644
- const networks = ["devnet", "simnet", "testnet", "mainnet"];
645
- const folder = (0, import_path7.resolve)(process.cwd(), config.outputDir, "deployments");
646
- await (0, import_promises6.mkdir)(folder, { recursive: true });
647
- const generates = networks.map((n) => generateDeployment(n, config));
648
- await Promise.all(generates);
649
- }
650
651
 
651
- // src/utils.ts
652
- var generateFilesForContract = async ({
653
- contractFile: _contractFile,
652
+ // src/contract.ts
653
+ var import_promises7 = require("fs/promises");
654
+ var import_path8 = require("path");
655
+ var generateFilesForContractWithSession = async ({
654
656
  outputFolder,
655
- provider,
656
- contractAddress,
657
+ sessionContract,
657
658
  dirName,
658
- contractName,
659
- docsPath
659
+ docsPath,
660
+ contractFile
660
661
  }) => {
661
- const contractFile = (0, import_path8.resolve)(process.cwd(), _contractFile);
662
- const contractIdentifier = `${contractAddress}.${contractName}`;
663
- const abi = await (0, import_native_bin2.deployContract)({
664
- contractIdentifier,
665
- contractFilePath: contractFile,
666
- provider
667
- });
668
- const variables = await getVariables({
669
- abi,
670
- contractIdentifier,
671
- provider
672
- });
662
+ const contractIdentifier = sessionContract.contract_id;
663
+ const [contractAddress, contractName] = contractIdentifier.split(".");
664
+ const abi = sessionContract.contract_interface;
665
+ const variables = [];
673
666
  const typesFile = generateTypesFile(abi, contractName);
674
667
  const indexFile = generateIndexFile({
675
668
  contractFile: (0, import_path8.relative)(process.cwd(), contractFile),
@@ -688,9 +681,9 @@ var generateFilesForContract = async ({
688
681
  }
689
682
  const outputPath = (0, import_path8.resolve)(outputFolder, dirName || ".", contractName);
690
683
  await (0, import_promises7.mkdir)(outputPath, { recursive: true });
691
- await writeFile2((0, import_path8.resolve)(outputPath, "abi.ts"), abiFile);
692
- await writeFile2((0, import_path8.resolve)(outputPath, "index.ts"), indexFile);
693
- await writeFile2((0, import_path8.resolve)(outputPath, "types.ts"), typesFile);
684
+ await writeFile((0, import_path8.resolve)(outputPath, "abi.ts"), abiFile);
685
+ await writeFile((0, import_path8.resolve)(outputPath, "index.ts"), indexFile);
686
+ await writeFile((0, import_path8.resolve)(outputPath, "types.ts"), typesFile);
694
687
  return {
695
688
  abi,
696
689
  contractFile,
@@ -700,39 +693,42 @@ var generateFilesForContract = async ({
700
693
  variables
701
694
  };
702
695
  };
696
+
697
+ // src/utils.ts
703
698
  var generateProject = async (projectPath) => {
704
699
  const configFile = await getProjectConfig(projectPath);
705
700
  const { contractsDir, outputDir, contracts } = configFile;
706
- const outputFolder = (0, import_path8.resolve)(projectPath, outputDir);
701
+ const outputFolder = (0, import_path9.resolve)(projectPath, outputDir);
707
702
  const provider = await (0, import_native_bin2.createClarityBin)();
708
703
  const metas = [];
709
- for (const contract of contracts) {
710
- const contractFile = (0, import_path8.resolve)(projectPath, contractsDir, contract.file);
711
- const dirName = (0, import_path8.dirname)(contract.file);
712
- const meta = await generateFilesForContract({
713
- contractFile,
704
+ const session = await getClarinetSession((0, import_path9.resolve)(projectPath, configFile.clarinet));
705
+ for (const contract of session.contracts) {
706
+ const configContract = contracts.find((c) => c.name === contract.contract_id.split(".")[1]);
707
+ if (typeof configContract === "undefined") {
708
+ throw new Error(`No config contract found for ${contract.contract_id}`);
709
+ }
710
+ const contractFile = (0, import_path9.resolve)(projectPath, configFile.clarinet, configContract.file);
711
+ const meta = await generateFilesForContractWithSession({
712
+ sessionContract: contract,
714
713
  outputFolder,
715
- provider,
716
- contractAddress: contract.address,
717
- dirName,
718
- contractName: contract.name,
719
- docsPath: configFile.docs
714
+ docsPath: configFile.docs,
715
+ contractFile
720
716
  });
721
717
  metas.push(meta);
722
718
  }
723
719
  const indexFile = generateProjectIndexFile(configFile);
724
720
  await generateDocsIndex(configFile);
725
- const indexPath = (0, import_path8.resolve)(outputFolder, "index.ts");
726
- await writeFile2(indexPath, indexFile);
721
+ const indexPath = (0, import_path9.resolve)(outputFolder, "index.ts");
722
+ await writeFile(indexPath, indexFile);
727
723
  const singleFile = await generateSingleFile(configFile, metas);
728
- const singlePath = (0, import_path8.resolve)(outputFolder, "single.ts");
729
- await writeFile2(singlePath, singleFile);
724
+ const singlePath = (0, import_path9.resolve)(outputFolder, "single.ts");
725
+ await writeFile(singlePath, singleFile);
730
726
  await generateDeployments(configFile);
731
727
  };
732
728
 
733
729
  // src/commands/index.ts
734
730
  var import_chokidar = require("chokidar");
735
- var import_path9 = require("path");
731
+ var import_path10 = require("path");
736
732
  var import_chalk = require("chalk");
737
733
  var import_ora = __toESM(require("ora"));
738
734
  var _Generate = class extends import_command2.Command {
@@ -754,7 +750,7 @@ ${String(error.message)}`);
754
750
  }
755
751
  watcher.on("change", (path) => {
756
752
  const cb = async () => {
757
- const file = (0, import_path9.basename)(path);
753
+ const file = (0, import_path10.basename)(path);
758
754
  spinner.clear();
759
755
  spinner.start(`Change detected for ${(0, import_chalk.green)(file)}, generating.`);
760
756
  try {
@@ -776,7 +772,11 @@ ${msg}`);
776
772
  void cb();
777
773
  });
778
774
  } else {
779
- await generateProject(cwd);
775
+ try {
776
+ await generateProject(cwd);
777
+ } catch (error) {
778
+ console.log(error);
779
+ }
780
780
  }
781
781
  }
782
782
  };
package/dist/index.js CHANGED
@@ -70,29 +70,112 @@ module.exports = __toCommonJS(src_exports);
70
70
  var import_command2 = require("@oclif/command");
71
71
 
72
72
  // src/config.ts
73
- var import_path2 = require("path");
74
- var import_promises2 = require("fs/promises");
75
- var import_fs = require("fs");
73
+ var import_path4 = require("path");
74
+ var import_promises4 = require("fs/promises");
75
+ var import_fs2 = require("fs");
76
76
 
77
77
  // src/clarinet-config.ts
78
78
  var import_toml = require("@iarna/toml");
79
- var import_path = require("path");
80
- var import_promises = require("fs/promises");
79
+ var import_path3 = require("path");
80
+ var import_promises3 = require("fs/promises");
81
81
  var import_wallet_sdk = require("micro-stacks/wallet-sdk");
82
82
  var import_toposort = require("toposort");
83
83
  var import_crypto = require("micro-stacks/crypto");
84
+
85
+ // src/generate/deployment.ts
86
+ var import_js_yaml = require("js-yaml");
87
+ var import_promises2 = require("fs/promises");
88
+ var import_path2 = require("path");
89
+ var import_fs = require("fs");
90
+
91
+ // src/writer.ts
92
+ var import_promises = require("fs/promises");
93
+ var import_path = require("path");
94
+ var import_prettier = require("prettier");
95
+ var defaultPrettierConfig = {
96
+ printWidth: 80,
97
+ semi: true,
98
+ singleQuote: true,
99
+ trailingComma: "es5"
100
+ };
101
+ async function resolvePrettierConfig() {
102
+ try {
103
+ const local = await (0, import_prettier.resolveConfig)(process.cwd());
104
+ if (local)
105
+ return local;
106
+ } catch (error) {
107
+ }
108
+ return defaultPrettierConfig;
109
+ }
110
+ async function formatFile(contents, path) {
111
+ try {
112
+ const fileName = (0, import_path.basename)(path);
113
+ const config = await resolvePrettierConfig();
114
+ const formatted = (0, import_prettier.format)(contents, __spreadProps(__spreadValues({}, config), {
115
+ filepath: fileName
116
+ }));
117
+ return formatted;
118
+ } catch (error) {
119
+ }
120
+ return contents;
121
+ }
122
+ async function writeFile(path, contents) {
123
+ const formatted = await formatFile(contents, path);
124
+ await (0, import_promises.writeFile)(path, formatted);
125
+ }
126
+
127
+ // src/generate/deployment.ts
128
+ async function parseDeployment(path) {
129
+ const contents = await (0, import_promises2.readFile)(path, { encoding: "utf-8" });
130
+ const parsed = (0, import_js_yaml.load)(contents);
131
+ return parsed;
132
+ }
133
+ async function generateDeployment(network, config) {
134
+ const file = `default.${network}-plan.yaml`;
135
+ const deploymentPath = (0, import_path2.resolve)(process.cwd(), config.clarinet, "deployments", file);
136
+ if ((0, import_fs.existsSync)(deploymentPath)) {
137
+ const plan = await parseDeployment(deploymentPath);
138
+ const varName = `${network}Deployment`;
139
+ const contents = `export const ${varName} = ${JSON.stringify(plan)} as const;
140
+ `;
141
+ const outputFile = (0, import_path2.resolve)(config.outputDir, "deployments", `${network}.ts`);
142
+ await writeFile(outputFile, contents);
143
+ }
144
+ }
145
+ async function generateDeployments(config) {
146
+ const networks = ["devnet", "simnet", "testnet", "mainnet"];
147
+ const folder = (0, import_path2.resolve)(process.cwd(), config.outputDir, "deployments");
148
+ await (0, import_promises2.mkdir)(folder, { recursive: true });
149
+ const generates = networks.map((n) => generateDeployment(n, config));
150
+ await Promise.all(generates);
151
+ }
152
+
153
+ // src/clarinet-config.ts
84
154
  async function getClarinetDevConfig(folder) {
85
- const baseConfigPath = (0, import_path.resolve)(folder, "settings", "Devnet.toml");
86
- const configContents = await (0, import_promises.readFile)(baseConfigPath, { encoding: "utf-8" });
155
+ const baseConfigPath = (0, import_path3.resolve)(folder, "settings", "Devnet.toml");
156
+ const configContents = await (0, import_promises3.readFile)(baseConfigPath, { encoding: "utf-8" });
87
157
  const config = (0, import_toml.parse)(configContents);
88
158
  return config;
89
159
  }
90
160
  async function getClarinetConfig(folder) {
91
- const baseConfigPath = (0, import_path.resolve)(folder, "Clarinet.toml");
92
- const configContents = await (0, import_promises.readFile)(baseConfigPath, { encoding: "utf-8" });
161
+ const baseConfigPath = (0, import_path3.resolve)(folder, "Clarinet.toml");
162
+ const configContents = await (0, import_promises3.readFile)(baseConfigPath, { encoding: "utf-8" });
93
163
  const config = (0, import_toml.parse)(configContents);
94
164
  return config;
95
165
  }
166
+ async function getContractsFromDeployment(clarinetPath) {
167
+ const simnetPath = (0, import_path3.resolve)(clarinetPath || process.cwd(), "deployments/default.simnet-plan.yaml");
168
+ const deployment = await parseDeployment(simnetPath);
169
+ const txs = deployment.plan.batches[0].transactions;
170
+ return txs.map((_tx) => {
171
+ const tx = _tx["emulated-contract-publish"];
172
+ return {
173
+ file: tx.path,
174
+ name: tx["contract-name"],
175
+ address: tx["emulated-sender"]
176
+ };
177
+ });
178
+ }
96
179
  function getContractsFromClarinet(clarinetConfig, accounts) {
97
180
  const deployerAddress = accounts.deployer.address;
98
181
  const sortedContracts = sortClarinetContracts(clarinetConfig.contracts);
@@ -141,11 +224,11 @@ var defaultConfigFile = {
141
224
  clarinet: "."
142
225
  };
143
226
  function configFilePath(rootPath) {
144
- return (0, import_path2.resolve)(rootPath, "clarigen.config.json");
227
+ return (0, import_path4.resolve)(rootPath, "clarigen.config.json");
145
228
  }
146
229
  async function configFileExists(configPath) {
147
230
  try {
148
- await (0, import_promises2.access)(configPath, import_fs.constants.R_OK);
231
+ await (0, import_promises4.access)(configPath, import_fs2.constants.R_OK);
149
232
  return true;
150
233
  } catch (error) {
151
234
  return false;
@@ -155,7 +238,7 @@ async function getConfigFile(rootPath) {
155
238
  const fullPath = configFilePath(rootPath);
156
239
  const exists = await configFileExists(fullPath);
157
240
  if (exists) {
158
- const configContents = await (0, import_promises2.readFile)(fullPath, { encoding: "utf-8" });
241
+ const configContents = await (0, import_promises4.readFile)(fullPath, { encoding: "utf-8" });
159
242
  const configFile = JSON.parse(configContents);
160
243
  return __spreadValues(__spreadValues({}, defaultConfigFile), configFile);
161
244
  }
@@ -164,11 +247,16 @@ async function getConfigFile(rootPath) {
164
247
  async function getProjectConfig(rootPath) {
165
248
  var _a, _b;
166
249
  const configFile = await getConfigFile(rootPath);
167
- const clarinetPath = (0, import_path2.resolve)(rootPath, configFile.clarinet);
250
+ const clarinetPath = (0, import_path4.resolve)(rootPath, configFile.clarinet);
168
251
  const clarinet = await getClarinetConfig(clarinetPath);
169
252
  const accounts = await getClarinetAccounts(clarinetPath);
170
- const contracts = getContractsFromClarinet(clarinet, accounts);
171
- const contractsDir = (0, import_path2.relative)(process.cwd(), (0, import_path2.join)(configFile.clarinet, "contracts"));
253
+ let contracts;
254
+ try {
255
+ contracts = await getContractsFromDeployment(clarinetPath);
256
+ } catch (error) {
257
+ contracts = getContractsFromClarinet(clarinet, accounts);
258
+ }
259
+ const contractsDir = (0, import_path4.relative)(process.cwd(), (0, import_path4.join)(configFile.clarinet, "contracts"));
172
260
  return __spreadProps(__spreadValues({}, configFile), {
173
261
  outputDir: ((_a = clarinet.clarigen) == null ? void 0 : _a.output_dir) || configFile.outputDir,
174
262
  docs: ((_b = clarinet.clarigen) == null ? void 0 : _b.docs) || configFile.docs,
@@ -282,7 +370,7 @@ function makePureTypes(abi) {
282
370
 
283
371
  // src/generate/files.ts
284
372
  var import_core2 = require("@clarigen/core");
285
- var import_path3 = require("path");
373
+ var import_path5 = require("path");
286
374
  var generateInterfaceFile = ({
287
375
  contractName,
288
376
  abi
@@ -369,8 +457,8 @@ export const accounts = {
369
457
  const contractVar = (0, import_core2.toCamelCase)(contractName);
370
458
  const contractInfo = `${contractVar}Info`;
371
459
  const contractInterface = `${(0, import_core2.toCamelCase)(contractName, true)}Contract`;
372
- const dirName = (0, import_path3.dirname)(contract.file);
373
- const importPath = `'./${(0, import_path3.join)(dirName || ".", contractName)}'`;
460
+ const dirName = (0, import_path5.dirname)(contract.file);
461
+ const importPath = `'./${contractName}'`;
374
462
  const _import = `import { ${contractInfo} } from ${importPath};`;
375
463
  imports.push(_import);
376
464
  const _export = `export type { ${contractInterface} } from ${importPath};`;
@@ -396,13 +484,13 @@ var import_command = require("@oclif/command");
396
484
 
397
485
  // src/utils.ts
398
486
  var import_native_bin2 = require("@clarigen/native-bin");
399
- var import_path8 = require("path");
400
- var import_promises7 = require("fs/promises");
487
+ var import_path9 = require("path");
488
+ var import_promises8 = require("fs/promises");
401
489
 
402
490
  // src/docs.ts
403
491
  var import_claridocs = require("@clarigen/claridocs");
404
- var import_promises3 = require("fs/promises");
405
- var import_path4 = require("path");
492
+ var import_promises5 = require("fs/promises");
493
+ var import_path6 = require("path");
406
494
  async function generateMarkdownDoc({
407
495
  contractFile,
408
496
  contractName,
@@ -410,18 +498,18 @@ async function generateMarkdownDoc({
410
498
  abi,
411
499
  dirName
412
500
  }) {
413
- const contractSrc = await (0, import_promises3.readFile)(contractFile, { encoding: "utf-8" });
501
+ const contractSrc = await (0, import_promises5.readFile)(contractFile, { encoding: "utf-8" });
414
502
  const docs = (0, import_claridocs.createContractDocInfo)({ contractSrc, abi });
415
- const folder = (0, import_path4.resolve)(process.cwd(), docsPath, dirName || ".");
416
- const filePath = (0, import_path4.resolve)(folder, `${contractName}.md`);
503
+ const folder = (0, import_path6.resolve)(process.cwd(), docsPath, dirName || ".");
504
+ const filePath = (0, import_path6.resolve)(folder, `${contractName}.md`);
417
505
  const md = (0, import_claridocs.generateMarkdown)({
418
506
  contract: docs,
419
- contractFile: (0, import_path4.relative)(folder, contractFile),
507
+ contractFile: (0, import_path6.relative)(folder, contractFile),
420
508
  contractName,
421
509
  abi
422
510
  });
423
- await (0, import_promises3.mkdir)(folder, { recursive: true });
424
- await (0, import_promises3.writeFile)(filePath, md);
511
+ await (0, import_promises5.mkdir)(folder, { recursive: true });
512
+ await (0, import_promises5.writeFile)(filePath, md);
425
513
  }
426
514
  async function generateDocsIndex(configFile) {
427
515
  if (!configFile.docs)
@@ -434,14 +522,14 @@ async function generateDocsIndex(configFile) {
434
522
 
435
523
  ${contractLines.join("\n")}
436
524
  `;
437
- const filepath = (0, import_path4.resolve)(process.cwd(), configFile.docs, "README.md");
438
- await (0, import_promises3.writeFile)(filepath, fileContents);
525
+ const filepath = (0, import_path6.resolve)(process.cwd(), configFile.docs, "README.md");
526
+ await (0, import_promises5.writeFile)(filepath, fileContents);
439
527
  }
440
528
 
441
529
  // src/generate/single.ts
442
530
  var import_core3 = require("@clarigen/core");
443
- var import_path5 = require("path");
444
- var import_promises4 = require("fs/promises");
531
+ var import_path7 = require("path");
532
+ var import_promises6 = require("fs/promises");
445
533
  var import_util = require("util");
446
534
  function generateContractMeta(contract) {
447
535
  const { abi } = contract;
@@ -479,7 +567,7 @@ function generateContractMeta(contract) {
479
567
  return mapLine;
480
568
  });
481
569
  const otherAbi = JSON.stringify(rest);
482
- const contractFile = (0, import_path5.relative)(process.cwd(), contract.contractFile);
570
+ const contractFile = (0, import_path7.relative)(process.cwd(), contract.contractFile);
483
571
  return `{
484
572
  ${serializeLines("functions", functionLines)}
485
573
  ${serializeLines("variables", variableLines)}
@@ -544,143 +632,48 @@ function serializeLines(key, lines) {
544
632
  },`;
545
633
  }
546
634
  async function getSingleTypes() {
547
- const typesPath = (0, import_path5.resolve)(__dirname, "../../dist/abi-types.ts.txt");
548
- const typesFile = await (0, import_promises4.readFile)(typesPath, { encoding: "utf-8" });
635
+ const typesPath = (0, import_path7.resolve)(__dirname, "../../dist/abi-types.ts.txt");
636
+ const typesFile = await (0, import_promises6.readFile)(typesPath, { encoding: "utf-8" });
549
637
  return typesFile;
550
638
  }
551
639
 
552
- // src/writer.ts
553
- var import_promises5 = require("fs/promises");
554
- var import_path6 = require("path");
555
- var import_prettier = require("prettier");
556
- var defaultPrettierConfig = {
557
- printWidth: 80,
558
- semi: true,
559
- singleQuote: true,
560
- trailingComma: "es5"
561
- };
562
- async function resolvePrettierConfig() {
563
- try {
564
- const local = await (0, import_prettier.resolveConfig)(process.cwd());
565
- if (local)
566
- return local;
567
- } catch (error) {
568
- }
569
- return defaultPrettierConfig;
570
- }
571
- async function formatFile(contents, path) {
572
- try {
573
- const fileName = (0, import_path6.basename)(path);
574
- const config = await resolvePrettierConfig();
575
- const formatted = (0, import_prettier.format)(contents, __spreadProps(__spreadValues({}, config), {
576
- filepath: fileName
577
- }));
578
- return formatted;
579
- } catch (error) {
580
- }
581
- return contents;
582
- }
583
- async function writeFile2(path, contents) {
584
- const formatted = await formatFile(contents, path);
585
- await (0, import_promises5.writeFile)(path, formatted);
586
- }
587
-
588
640
  // src/generate/vars.ts
589
641
  var import_core4 = require("@clarigen/core");
590
642
  var import_native_bin = require("@clarigen/native-bin");
591
643
  var import_clarity = require("micro-stacks/clarity");
592
- async function getVariables({
593
- abi,
594
- contractIdentifier,
595
- provider
596
- }) {
597
- const variableTransforms = abi.variables.map((variable) => {
598
- return evalVariable({
599
- variable,
600
- provider,
601
- contractIdentifier
602
- });
603
- });
604
- const variables = await Promise.all(variableTransforms);
605
- return variables;
606
- }
607
- async function evalVariable({
608
- contractIdentifier,
609
- variable,
610
- provider
611
- }) {
612
- const code = getEvalCode(variable);
613
- const result = await (0, import_native_bin.evalRaw)({
614
- contractAddress: contractIdentifier,
615
- code,
616
- provider
617
- });
618
- const resultCV = (0, import_clarity.hexToCV)(result.output_serialized);
619
- const value = (0, import_core4.cvToValue)(resultCV, true);
620
- return __spreadProps(__spreadValues({}, variable), {
621
- defaultValue: value
622
- });
623
- }
624
- function getEvalCode(variable) {
625
- const { access: access2 } = variable;
626
- if (access2 === "variable") {
627
- return `(var-get ${variable.name})`;
628
- }
629
- return variable.name;
630
- }
631
644
 
632
- // src/generate/deployment.ts
633
- var import_js_yaml = require("js-yaml");
634
- var import_promises6 = require("fs/promises");
635
- var import_path7 = require("path");
636
- var import_fs2 = require("fs");
637
- async function parseDeployment(path) {
638
- const contents = await (0, import_promises6.readFile)(path, { encoding: "utf-8" });
639
- const parsed = (0, import_js_yaml.load)(contents);
640
- return parsed;
641
- }
642
- async function generateDeployment(network, config) {
643
- const file = `default.${network}-plan.yaml`;
644
- const deploymentPath = (0, import_path7.resolve)(process.cwd(), config.clarinet, "deployments", file);
645
- if ((0, import_fs2.existsSync)(deploymentPath)) {
646
- const plan = await parseDeployment(deploymentPath);
647
- const varName = `${network}Deployment`;
648
- const contents = `export const ${varName} = ${JSON.stringify(plan)} as const;
649
- `;
650
- const outputFile = (0, import_path7.resolve)(config.outputDir, "deployments", `${network}.ts`);
651
- await writeFile2(outputFile, contents);
645
+ // src/deno-run.ts
646
+ var import_child_process = require("child_process");
647
+ var import_util2 = require("util");
648
+ var exec = (0, import_util2.promisify)(import_child_process.exec);
649
+ async function getClarinetSession(cwd) {
650
+ const scriptPath = "https://raw.githubusercontent.com/mechanismHQ/clarigen-deno/main/src/cli/print.ts";
651
+ const command = `clarinet run ${scriptPath}`;
652
+ try {
653
+ const result = await exec(command, { cwd });
654
+ const sessionJSON = result.stdout.split("\n")[1];
655
+ const session = JSON.parse(sessionJSON);
656
+ return session;
657
+ } catch (error) {
658
+ console.error(`Error getting clarinet session`);
659
+ throw error;
652
660
  }
653
661
  }
654
- async function generateDeployments(config) {
655
- const networks = ["devnet", "simnet", "testnet", "mainnet"];
656
- const folder = (0, import_path7.resolve)(process.cwd(), config.outputDir, "deployments");
657
- await (0, import_promises6.mkdir)(folder, { recursive: true });
658
- const generates = networks.map((n) => generateDeployment(n, config));
659
- await Promise.all(generates);
660
- }
661
662
 
662
- // src/utils.ts
663
- var generateFilesForContract = async ({
664
- contractFile: _contractFile,
663
+ // src/contract.ts
664
+ var import_promises7 = require("fs/promises");
665
+ var import_path8 = require("path");
666
+ var generateFilesForContractWithSession = async ({
665
667
  outputFolder,
666
- provider,
667
- contractAddress,
668
+ sessionContract,
668
669
  dirName,
669
- contractName,
670
- docsPath
670
+ docsPath,
671
+ contractFile
671
672
  }) => {
672
- const contractFile = (0, import_path8.resolve)(process.cwd(), _contractFile);
673
- const contractIdentifier = `${contractAddress}.${contractName}`;
674
- const abi = await (0, import_native_bin2.deployContract)({
675
- contractIdentifier,
676
- contractFilePath: contractFile,
677
- provider
678
- });
679
- const variables = await getVariables({
680
- abi,
681
- contractIdentifier,
682
- provider
683
- });
673
+ const contractIdentifier = sessionContract.contract_id;
674
+ const [contractAddress, contractName] = contractIdentifier.split(".");
675
+ const abi = sessionContract.contract_interface;
676
+ const variables = [];
684
677
  const typesFile = generateTypesFile(abi, contractName);
685
678
  const indexFile = generateIndexFile({
686
679
  contractFile: (0, import_path8.relative)(process.cwd(), contractFile),
@@ -699,9 +692,9 @@ var generateFilesForContract = async ({
699
692
  }
700
693
  const outputPath = (0, import_path8.resolve)(outputFolder, dirName || ".", contractName);
701
694
  await (0, import_promises7.mkdir)(outputPath, { recursive: true });
702
- await writeFile2((0, import_path8.resolve)(outputPath, "abi.ts"), abiFile);
703
- await writeFile2((0, import_path8.resolve)(outputPath, "index.ts"), indexFile);
704
- await writeFile2((0, import_path8.resolve)(outputPath, "types.ts"), typesFile);
695
+ await writeFile((0, import_path8.resolve)(outputPath, "abi.ts"), abiFile);
696
+ await writeFile((0, import_path8.resolve)(outputPath, "index.ts"), indexFile);
697
+ await writeFile((0, import_path8.resolve)(outputPath, "types.ts"), typesFile);
705
698
  return {
706
699
  abi,
707
700
  contractFile,
@@ -711,39 +704,42 @@ var generateFilesForContract = async ({
711
704
  variables
712
705
  };
713
706
  };
707
+
708
+ // src/utils.ts
714
709
  var generateProject = async (projectPath) => {
715
710
  const configFile = await getProjectConfig(projectPath);
716
711
  const { contractsDir, outputDir, contracts } = configFile;
717
- const outputFolder = (0, import_path8.resolve)(projectPath, outputDir);
712
+ const outputFolder = (0, import_path9.resolve)(projectPath, outputDir);
718
713
  const provider = await (0, import_native_bin2.createClarityBin)();
719
714
  const metas = [];
720
- for (const contract of contracts) {
721
- const contractFile = (0, import_path8.resolve)(projectPath, contractsDir, contract.file);
722
- const dirName = (0, import_path8.dirname)(contract.file);
723
- const meta = await generateFilesForContract({
724
- contractFile,
715
+ const session = await getClarinetSession((0, import_path9.resolve)(projectPath, configFile.clarinet));
716
+ for (const contract of session.contracts) {
717
+ const configContract = contracts.find((c) => c.name === contract.contract_id.split(".")[1]);
718
+ if (typeof configContract === "undefined") {
719
+ throw new Error(`No config contract found for ${contract.contract_id}`);
720
+ }
721
+ const contractFile = (0, import_path9.resolve)(projectPath, configFile.clarinet, configContract.file);
722
+ const meta = await generateFilesForContractWithSession({
723
+ sessionContract: contract,
725
724
  outputFolder,
726
- provider,
727
- contractAddress: contract.address,
728
- dirName,
729
- contractName: contract.name,
730
- docsPath: configFile.docs
725
+ docsPath: configFile.docs,
726
+ contractFile
731
727
  });
732
728
  metas.push(meta);
733
729
  }
734
730
  const indexFile = generateProjectIndexFile(configFile);
735
731
  await generateDocsIndex(configFile);
736
- const indexPath = (0, import_path8.resolve)(outputFolder, "index.ts");
737
- await writeFile2(indexPath, indexFile);
732
+ const indexPath = (0, import_path9.resolve)(outputFolder, "index.ts");
733
+ await writeFile(indexPath, indexFile);
738
734
  const singleFile = await generateSingleFile(configFile, metas);
739
- const singlePath = (0, import_path8.resolve)(outputFolder, "single.ts");
740
- await writeFile2(singlePath, singleFile);
735
+ const singlePath = (0, import_path9.resolve)(outputFolder, "single.ts");
736
+ await writeFile(singlePath, singleFile);
741
737
  await generateDeployments(configFile);
742
738
  };
743
739
 
744
740
  // src/commands/index.ts
745
741
  var import_chokidar = require("chokidar");
746
- var import_path9 = require("path");
742
+ var import_path10 = require("path");
747
743
  var import_chalk = require("chalk");
748
744
  var import_ora = __toESM(require("ora"));
749
745
  var _Generate = class extends import_command.Command {
@@ -765,7 +761,7 @@ ${String(error.message)}`);
765
761
  }
766
762
  watcher.on("change", (path) => {
767
763
  const cb = async () => {
768
- const file = (0, import_path9.basename)(path);
764
+ const file = (0, import_path10.basename)(path);
769
765
  spinner.clear();
770
766
  spinner.start(`Change detected for ${(0, import_chalk.green)(file)}, generating.`);
771
767
  try {
@@ -787,7 +783,11 @@ ${msg}`);
787
783
  void cb();
788
784
  });
789
785
  } else {
790
- await generateProject(cwd);
786
+ try {
787
+ await generateProject(cwd);
788
+ } catch (error) {
789
+ console.log(error);
790
+ }
791
791
  }
792
792
  }
793
793
  };
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.24",
5
+ "version": "1.0.0-next.25",
6
6
  "license": "MIT",
7
7
  "types": "./dist/index.d.ts",
8
8
  "main": "./dist/index.js",
@@ -38,9 +38,9 @@
38
38
  "ts-node": "^9.1.1"
39
39
  },
40
40
  "dependencies": {
41
- "@clarigen/claridocs": "1.0.0-next.24",
42
- "@clarigen/core": "1.0.0-next.24",
43
- "@clarigen/native-bin": "1.0.0-next.24",
41
+ "@clarigen/claridocs": "1.0.0-next.25",
42
+ "@clarigen/core": "1.0.0-next.25",
43
+ "@clarigen/native-bin": "1.0.0-next.25",
44
44
  "@iarna/toml": "^2.2.5",
45
45
  "@oclif/command": "^1.8.0",
46
46
  "@oclif/config": "^1.17.0",
@@ -69,6 +69,6 @@
69
69
  "lint": "eslint \"src/**/*.{ts,tsx}\" && prettier --check src/**/*.ts",
70
70
  "typecheck": "tsc --noEmit -p tsconfig-test.json",
71
71
  "demo": "pnpm build && node bin/run",
72
- "publish:dev": "yalc publish --push"
72
+ "publish:dev": "pnpm build && yalc publish --push"
73
73
  }
74
74
  }
@@ -8,6 +8,8 @@ import {
8
8
  } from 'micro-stacks/wallet-sdk';
9
9
  import { array as toposort } from 'toposort';
10
10
  import { StacksNetworkVersion } from 'micro-stacks/crypto';
11
+ import { parseDeployment } from './generate/deployment';
12
+ import { SimnetDeploymentPlan } from '@clarigen/core';
11
13
 
12
14
  interface ClarinetConfigAccount {
13
15
  mnemonic: string;
@@ -63,6 +65,27 @@ export async function getClarinetConfig(folder: string) {
63
65
  return config;
64
66
  }
65
67
 
68
+ export async function getContractsFromDeployment(
69
+ clarinetPath?: string
70
+ ): Promise<ConfigContract[]> {
71
+ const simnetPath = resolve(
72
+ clarinetPath || process.cwd(),
73
+ 'deployments/default.simnet-plan.yaml'
74
+ );
75
+ const deployment = (await parseDeployment(
76
+ simnetPath
77
+ )) as SimnetDeploymentPlan;
78
+ const txs = deployment.plan.batches[0].transactions;
79
+ return txs.map((_tx) => {
80
+ const tx = _tx['emulated-contract-publish'];
81
+ return {
82
+ file: tx.path,
83
+ name: tx['contract-name'],
84
+ address: tx['emulated-sender'],
85
+ };
86
+ });
87
+ }
88
+
66
89
  export function getContractsFromClarinet(
67
90
  clarinetConfig: ClarinetConfig,
68
91
  accounts: ClarinetAccounts
@@ -66,7 +66,11 @@ export class Generate extends Command {
66
66
  void cb();
67
67
  });
68
68
  } else {
69
- await generateProject(cwd);
69
+ try {
70
+ await generateProject(cwd);
71
+ } catch (error) {
72
+ console.log(error);
73
+ }
70
74
  }
71
75
  }
72
76
  }
package/src/config.ts CHANGED
@@ -3,9 +3,11 @@ import { readFile, access } from 'fs/promises';
3
3
  import { constants } from 'fs';
4
4
  import {
5
5
  ClarinetAccounts,
6
+ ClarinetConfig,
6
7
  getClarinetAccounts,
7
8
  getClarinetConfig,
8
9
  getContractsFromClarinet,
10
+ getContractsFromDeployment,
9
11
  } from './clarinet-config';
10
12
 
11
13
  export interface ConfigContract {
@@ -66,7 +68,12 @@ export async function getProjectConfig(rootPath: string): Promise<ConfigFile> {
66
68
  const clarinetPath = resolve(rootPath, configFile.clarinet);
67
69
  const clarinet = await getClarinetConfig(clarinetPath);
68
70
  const accounts = await getClarinetAccounts(clarinetPath);
69
- const contracts = getContractsFromClarinet(clarinet, accounts);
71
+ let contracts: ConfigContract[];
72
+ try {
73
+ contracts = await getContractsFromDeployment(clarinetPath);
74
+ } catch (error) {
75
+ contracts = getContractsFromClarinet(clarinet, accounts);
76
+ }
70
77
  const contractsDir = relative(
71
78
  process.cwd(),
72
79
  join(configFile.clarinet, 'contracts')
@@ -0,0 +1,65 @@
1
+ import { mkdir } from 'fs/promises';
2
+ import { relative, resolve } from 'path';
3
+ import { SessionContract } from './deno-run';
4
+ import { generateMarkdownDoc } from './docs';
5
+ import {
6
+ generateTypesFile,
7
+ generateIndexFile,
8
+ generateInterfaceFile,
9
+ } from './generate/files';
10
+ import { ContractMeta } from './utils';
11
+ import { writeFile } from './writer';
12
+
13
+ export const generateFilesForContractWithSession = async ({
14
+ outputFolder,
15
+ sessionContract,
16
+ dirName,
17
+ docsPath,
18
+ contractFile,
19
+ }: {
20
+ outputFolder: string;
21
+ sessionContract: SessionContract;
22
+ dirName?: string;
23
+ docsPath?: string;
24
+ contractFile: string;
25
+ }): Promise<ContractMeta> => {
26
+ const contractIdentifier = sessionContract.contract_id;
27
+ const [contractAddress, contractName] = contractIdentifier.split('.');
28
+
29
+ const abi = sessionContract.contract_interface;
30
+ const variables = [];
31
+
32
+ const typesFile = generateTypesFile(abi, contractName);
33
+ const indexFile = generateIndexFile({
34
+ contractFile: relative(process.cwd(), contractFile),
35
+ contractAddress: contractAddress,
36
+ contractName,
37
+ });
38
+ const abiFile = generateInterfaceFile({ contractName, abi });
39
+
40
+ if (typeof docsPath !== 'undefined') {
41
+ await generateMarkdownDoc({
42
+ contractFile,
43
+ contractName,
44
+ abi,
45
+ docsPath,
46
+ dirName,
47
+ });
48
+ }
49
+
50
+ const outputPath = resolve(outputFolder, dirName || '.', contractName);
51
+ await mkdir(outputPath, { recursive: true });
52
+
53
+ await writeFile(resolve(outputPath, 'abi.ts'), abiFile);
54
+ await writeFile(resolve(outputPath, 'index.ts'), indexFile);
55
+ await writeFile(resolve(outputPath, 'types.ts'), typesFile);
56
+
57
+ return {
58
+ abi,
59
+ contractFile,
60
+ contractName,
61
+ dirName,
62
+ contractAddress,
63
+ variables,
64
+ };
65
+ };
@@ -0,0 +1,35 @@
1
+ import { exec as _exec } from 'child_process';
2
+ import { promisify } from 'util';
3
+ import { homedir } from 'os';
4
+ import { resolve } from 'path';
5
+ import { ClarityAbi } from '@clarigen/core';
6
+
7
+ const exec = promisify(_exec);
8
+
9
+ export interface SessionContract {
10
+ contract_id: string;
11
+ contract_interface: ClarityAbi;
12
+ source: string;
13
+ dependencies: string[];
14
+ }
15
+
16
+ export interface Session {
17
+ session_id: number;
18
+ accounts: any[];
19
+ contracts: SessionContract[];
20
+ }
21
+
22
+ export async function getClarinetSession(cwd?: string): Promise<Session> {
23
+ const scriptPath =
24
+ 'https://raw.githubusercontent.com/mechanismHQ/clarigen-deno/main/src/cli/print.ts';
25
+ const command = `clarinet run ${scriptPath}`;
26
+ try {
27
+ const result = await exec(command, { cwd });
28
+ const sessionJSON = result.stdout.split('\n')[1];
29
+ const session = JSON.parse(sessionJSON);
30
+ return session as Session;
31
+ } catch (error) {
32
+ console.error(`Error getting clarinet session`);
33
+ throw error;
34
+ }
35
+ }
@@ -107,7 +107,7 @@ export const accounts = {
107
107
  const contractInfo = `${contractVar}Info`;
108
108
  const contractInterface = `${toCamelCase(contractName, true)}Contract`;
109
109
  const dirName = dirname(contract.file);
110
- const importPath = `'./${join(dirName || '.', contractName)}'`;
110
+ const importPath = `'./${contractName}'`;
111
111
 
112
112
  const _import = `import { ${contractInfo} } from ${importPath};`;
113
113
  imports.push(_import);
package/src/utils.ts CHANGED
@@ -19,6 +19,8 @@ import { writeFile } from './writer';
19
19
  import { getVariables, TypedAbiVariable } from './generate/vars';
20
20
  import { ClarityAbiVariable } from 'micro-stacks/clarity';
21
21
  import { generateDeployments } from './generate/deployment';
22
+ import { getClarinetSession } from './deno-run';
23
+ import { generateFilesForContractWithSession } from './contract';
22
24
 
23
25
  export interface ContractMeta {
24
26
  abi: ClarityAbi;
@@ -101,18 +103,27 @@ export const generateProject = async (projectPath: string) => {
101
103
  const outputFolder = resolve(projectPath, outputDir);
102
104
  const provider = await createClarityBin();
103
105
  const metas: ContractMeta[] = [];
106
+ const session = await getClarinetSession(
107
+ resolve(projectPath, configFile.clarinet)
108
+ );
104
109
  // this needs to be serial
105
- for (const contract of contracts) {
106
- const contractFile = resolve(projectPath, contractsDir, contract.file);
107
- const dirName = dirname(contract.file);
108
- const meta = await generateFilesForContract({
109
- contractFile,
110
- outputFolder: outputFolder,
111
- provider,
112
- contractAddress: contract.address,
113
- dirName,
114
- contractName: contract.name,
110
+ for (const contract of session.contracts) {
111
+ const configContract = contracts.find(
112
+ (c) => c.name === contract.contract_id.split('.')[1]
113
+ );
114
+ if (typeof configContract === 'undefined') {
115
+ throw new Error(`No config contract found for ${contract.contract_id}`);
116
+ }
117
+ const contractFile = resolve(
118
+ projectPath,
119
+ configFile.clarinet,
120
+ configContract.file
121
+ );
122
+ const meta = await generateFilesForContractWithSession({
123
+ sessionContract: contract,
124
+ outputFolder,
115
125
  docsPath: configFile.docs,
126
+ contractFile,
116
127
  });
117
128
  metas.push(meta);
118
129
  }