@clarigen/cli 1.0.0-next.18 → 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.
@@ -1,92 +1,757 @@
1
- var D=Object.defineProperty,jt=Object.defineProperties,Et=Object.getOwnPropertyDescriptor,It=Object.getOwnPropertyDescriptors,kt=Object.getOwnPropertyNames,S=Object.getOwnPropertySymbols;var H=Object.prototype.hasOwnProperty,rt=Object.prototype.propertyIsEnumerable;var et=(t,e,r)=>e in t?D(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,y=(t,e)=>{for(var r in e||(e={}))H.call(e,r)&&et(t,r,e[r]);if(S)for(var r of S(e))rt.call(e,r)&&et(t,r,e[r]);return t},x=(t,e)=>jt(t,It(e));var V=(t,e)=>{var r={};for(var n in t)H.call(t,n)&&e.indexOf(n)<0&&(r[n]=t[n]);if(t!=null&&S)for(var n of S(t))e.indexOf(n)<0&&rt.call(t,n)&&(r[n]=t[n]);return r};var St=(t,e)=>{for(var r in e)D(t,r,{get:e[r],enumerable:!0})},Dt=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of kt(e))!H.call(t,o)&&o!==r&&D(t,o,{get:()=>e[o],enumerable:!(n=Et(e,o))||n.enumerable});return t};var Vt=t=>Dt(D({},"__esModule",{value:!0}),t);var re={};St(re,{Generate:()=>w});module.exports=Vt(re);var E=require("@oclif/command");var Wt=require("@clarigen/native-bin"),F=require("@clarigen/core"),B=require("path");var Ut=require("@oclif/command");var h=require("path"),L=require("fs/promises"),ct=require("fs");var Q=require("@ltd/j-toml"),X=require("path"),Y=require("fs/promises"),O=require("micro-stacks/wallet-sdk"),nt=require("toposort"),ot=require("micro-stacks/crypto");async function Ot(t){let e=(0,X.resolve)(t,"settings","Devnet.toml"),r=await(0,Y.readFile)(e,{encoding:"utf-8"});return(0,Q.parse)(r,1,`
2
- `,!0,{longer:!0})}async function Lt(t){let e=(0,X.resolve)(t,"Clarinet.toml"),r=await(0,Y.readFile)(e,{encoding:"utf-8"});return(0,Q.parse)(r,1,`
3
- `,!0)}async function it(t,e){let r=await Lt(t),n=e.deployer.address;return Mt(r.contracts).map(a=>({file:r.contracts[a].path.replace(/^contracts\//,""),address:n,name:a}))}function Mt(t){let e=[],r=[];return Object.entries(t).forEach(([o,i])=>{r.push(o),i.depends_on.forEach(a=>e.push([o,a]))}),(0,nt.array)(r,e).reverse()}async function st(t){let e=await Ot(t),r=await Promise.all(Object.entries(e.accounts).map(async([o,i])=>{let a=await(0,O.generateWallet)(i.mnemonic,"password"),[s]=a.accounts,l=(0,O.getStxAddressFromAccount)(s,ot.StacksNetworkVersion.testnetP2PKH);return[o,x(y({},i),{address:l})]}));return Object.fromEntries(r)}var at={outputDir:"src/clarigen",clarinet:"."};function _t(t){return(0,h.resolve)(t,"clarigen.config.json")}async function Bt(t){try{return await(0,L.access)(t,ct.constants.R_OK),!0}catch{return!1}}async function Jt(t){let e=_t(t);if(await Bt(e)){let n=await(0,L.readFile)(e,{encoding:"utf-8"}),o=JSON.parse(n);return y(y({},at),o)}return at}async function M(t){let e=await Jt(t),r=(0,h.resolve)(t,e.clarinet||"."),n=await st(r),o=await it(r,n),i=(0,h.relative)(process.cwd(),(0,h.join)(e.clarinet,"contracts"));return x(y({},e),{contracts:o,contractsDir:i,accounts:n,clarinet:e.clarinet||"."})}var m=require("micro-stacks/transactions"),_=require("@clarigen/core"),lt=require("reserved-words"),p=(t,e=!1)=>{if((0,m.isClarityAbiPrimitive)(t)){if(t==="uint128")return e?"number | bigint":"bigint";if(t==="int128")return e?"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((0,m.isClarityAbiBuffer)(t))return"Uint8Array";if((0,m.isClarityAbiResponse)(t)){let r=p(t.response.ok),n=p(t.response.error);return`Response<${r}, ${n}>`}else{if((0,m.isClarityAbiOptional)(t))return`${p(t.optional)} | null`;if((0,m.isClarityAbiTuple)(t)){let r=[];return t.tuple.forEach(({name:n,type:o})=>{let i=p(o);r.push(`"${n}": ${i}`)}),`{
4
- ${r.join(`;
5
- `)}
6
- }`}else{if((0,m.isClarityAbiList)(t))return`${p(t.list.type)}[]`;if((0,m.isClarityAbiStringAscii)(t))return"string";if((0,m.isClarityAbiStringUtf8)(t))return"string";if(t==="trait_reference")return"string";throw new Error(`Unexpected Clarity ABI type: ${JSON.stringify(t)}`)}}}};function Z(t){let e=(0,_.toCamelCase)(t);return`${(0,lt.check)(e,6)?"_":""}${e}`}var Rt={public:"Public",read_only:"ReadOnly",private:"Private"};function ft(t){let e="";return t.functions.forEach((r,n)=>{let o=`${(0,_.toCamelCase)(r.name)}: `;if(o+=`(${r.args.map(s=>`${Z(s.name)}: ${p(s.type,!0)}`).join(", ")}) => `,o+=`ContractCalls.${Rt[r.access]}<`,r.access==="public"){let{type:s}=r.outputs;if(!(0,m.isClarityAbiResponse)(s))throw new Error("Expected response type for public function");let l=p(s.response.ok),f=p(s.response.error);o+=`${l}, ${f}>;`}else o+=`${p(r.outputs.type)}>;`;e+=`${n===0?"":`
7
- `} ${o}`}),t.maps.forEach(r=>{let n=`${(0,_.toCamelCase)(r.name)}: `,o=p(r.key,!0),i=`key: ${o}`,a=p(r.value);n+=`(${i}) => ContractCalls.Map<${o}, ${a}>;`,e+=`
8
- ${n}`}),e}var pt=({contractName:t,abi:e})=>{let r=(0,F.toCamelCase)(t,!0),s=e,{clarity_version:n}=s,o=V(s,["clarity_version"]),i=JSON.stringify(o,null,2);return`import { ClarityAbi } from '@clarigen/core';
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
9
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
+ var __spreadValues = (a, b) => {
11
+ for (var prop in b || (b = {}))
12
+ if (__hasOwnProp.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ if (__getOwnPropSymbols)
15
+ for (var prop of __getOwnPropSymbols(b)) {
16
+ if (__propIsEnum.call(b, prop))
17
+ __defNormalProp(a, prop, b[prop]);
18
+ }
19
+ return a;
20
+ };
21
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
22
+ var __objRest = (source, exclude) => {
23
+ var target = {};
24
+ for (var prop in source)
25
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
26
+ target[prop] = source[prop];
27
+ if (source != null && __getOwnPropSymbols)
28
+ for (var prop of __getOwnPropSymbols(source)) {
29
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
30
+ target[prop] = source[prop];
31
+ }
32
+ return target;
33
+ };
34
+ var __export = (target, all) => {
35
+ for (var name in all)
36
+ __defProp(target, name, { get: all[name], enumerable: true });
37
+ };
38
+ var __copyProps = (to, from, except, desc) => {
39
+ if (from && typeof from === "object" || typeof from === "function") {
40
+ for (let key of __getOwnPropNames(from))
41
+ if (!__hasOwnProp.call(to, key) && key !== except)
42
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
43
+ }
44
+ return to;
45
+ };
46
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
47
+
48
+ // src/commands/index.ts
49
+ var commands_exports = {};
50
+ __export(commands_exports, {
51
+ Generate: () => Generate
52
+ });
53
+ module.exports = __toCommonJS(commands_exports);
54
+ var import_command2 = require("@oclif/command");
55
+
56
+ // src/generate/files.ts
57
+ var import_native_bin = require("@clarigen/native-bin");
58
+ var import_core2 = require("@clarigen/core");
59
+ var import_path3 = require("path");
60
+
61
+ // src/index.ts
62
+ var import_command = require("@oclif/command");
63
+
64
+ // src/config.ts
65
+ var import_path2 = require("path");
66
+ var import_promises2 = require("fs/promises");
67
+ var import_fs = require("fs");
68
+
69
+ // src/clarinet-config.ts
70
+ var import_j_toml = require("@ltd/j-toml");
71
+ var import_path = require("path");
72
+ var import_promises = require("fs/promises");
73
+ var import_wallet_sdk = require("micro-stacks/wallet-sdk");
74
+ var import_toposort = require("toposort");
75
+ var import_crypto = require("micro-stacks/crypto");
76
+ async function getClarinetDevConfig(folder) {
77
+ const baseConfigPath = (0, import_path.resolve)(folder, "settings", "Devnet.toml");
78
+ const configContents = await (0, import_promises.readFile)(baseConfigPath, { encoding: "utf-8" });
79
+ const config = (0, import_j_toml.parse)(configContents, 1, "\n", true, {
80
+ longer: true
81
+ });
82
+ return config;
83
+ }
84
+ 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" });
87
+ const config = (0, import_j_toml.parse)(configContents, 1, "\n", true);
88
+ return config;
89
+ }
90
+ async function getContractsFromClarinet(folder, accounts) {
91
+ const clarinetConfig = await getClarinetConfig(folder);
92
+ const deployerAddress = accounts.deployer.address;
93
+ const sortedContracts = sortClarinetContracts(clarinetConfig.contracts);
94
+ const contracts = sortedContracts.map((contractName) => {
95
+ const info = clarinetConfig.contracts[contractName];
96
+ const file = info.path.replace(/^contracts\//, "");
97
+ return {
98
+ file,
99
+ address: deployerAddress,
100
+ name: contractName
101
+ };
102
+ });
103
+ return contracts;
104
+ }
105
+ function sortClarinetContracts(contractsConfig) {
106
+ const edges = [];
107
+ const nodes = [];
108
+ Object.entries(contractsConfig).forEach(([contractName, info]) => {
109
+ nodes.push(contractName);
110
+ info.depends_on.forEach((dependency) => edges.push([contractName, dependency]));
111
+ });
112
+ const sorted = (0, import_toposort.array)(nodes, edges).reverse();
113
+ return sorted;
114
+ }
115
+ async function getClarinetAccounts(folder) {
116
+ const devConfig = await getClarinetDevConfig(folder);
117
+ const accountEntries = await Promise.all(Object.entries(devConfig.accounts).map(async ([key, info]) => {
118
+ const wallet = await (0, import_wallet_sdk.generateWallet)(info.mnemonic, "password");
119
+ const [account] = wallet.accounts;
120
+ const address = (0, import_wallet_sdk.getStxAddressFromAccount)(account, import_crypto.StacksNetworkVersion.testnetP2PKH);
121
+ return [
122
+ key,
123
+ __spreadProps(__spreadValues({}, info), {
124
+ address
125
+ })
126
+ ];
127
+ }));
128
+ const accounts = Object.fromEntries(accountEntries);
129
+ return accounts;
130
+ }
131
+
132
+ // src/config.ts
133
+ var defaultConfigFile = {
134
+ outputDir: "src/clarigen",
135
+ clarinet: "."
136
+ };
137
+ function configFilePath(rootPath) {
138
+ return (0, import_path2.resolve)(rootPath, "clarigen.config.json");
139
+ }
140
+ async function configFileExists(configPath) {
141
+ try {
142
+ await (0, import_promises2.access)(configPath, import_fs.constants.R_OK);
143
+ return true;
144
+ } catch (error) {
145
+ return false;
146
+ }
147
+ }
148
+ async function getConfigFile(rootPath) {
149
+ const fullPath = configFilePath(rootPath);
150
+ const exists = await configFileExists(fullPath);
151
+ if (exists) {
152
+ const configContents = await (0, import_promises2.readFile)(fullPath, { encoding: "utf-8" });
153
+ const configFile = JSON.parse(configContents);
154
+ return __spreadValues(__spreadValues({}, defaultConfigFile), configFile);
155
+ }
156
+ return defaultConfigFile;
157
+ }
158
+ async function getProjectConfig(rootPath) {
159
+ const configFile = await getConfigFile(rootPath);
160
+ const clarinetPath = (0, import_path2.resolve)(rootPath, configFile.clarinet || ".");
161
+ const accounts = await getClarinetAccounts(clarinetPath);
162
+ const contracts = await getContractsFromClarinet(clarinetPath, accounts);
163
+ const contractsDir = (0, import_path2.relative)(process.cwd(), (0, import_path2.join)(configFile.clarinet, "contracts"));
164
+ return __spreadProps(__spreadValues({}, configFile), {
165
+ contracts,
166
+ contractsDir,
167
+ accounts,
168
+ clarinet: configFile.clarinet || "."
169
+ });
170
+ }
171
+
172
+ // src/generate/declaration.ts
173
+ var import_transactions = require("micro-stacks/transactions");
174
+ var import_core = require("@clarigen/core");
175
+ var import_reserved_words = require("reserved-words");
176
+ var jsTypeFromAbiType = (val, isArgument = false) => {
177
+ if ((0, import_transactions.isClarityAbiPrimitive)(val)) {
178
+ if (val === "uint128") {
179
+ if (isArgument)
180
+ return "number | bigint";
181
+ return "bigint";
182
+ } else if (val === "int128") {
183
+ if (isArgument)
184
+ return "number | bigint";
185
+ return "bigint";
186
+ } else if (val === "bool") {
187
+ return "boolean";
188
+ } else if (val === "principal") {
189
+ return "string";
190
+ } else if (val === "none") {
191
+ return "null";
192
+ } else if (val === "trait_reference") {
193
+ return "string";
194
+ } else {
195
+ throw new Error(`Unexpected Clarity ABI type primitive: ${JSON.stringify(val)}`);
196
+ }
197
+ } else if ((0, import_transactions.isClarityAbiBuffer)(val)) {
198
+ return "Uint8Array";
199
+ } else if ((0, import_transactions.isClarityAbiResponse)(val)) {
200
+ const ok = jsTypeFromAbiType(val.response.ok);
201
+ const err = jsTypeFromAbiType(val.response.error);
202
+ return `Response<${ok}, ${err}>`;
203
+ } else if ((0, import_transactions.isClarityAbiOptional)(val)) {
204
+ const innerType = jsTypeFromAbiType(val.optional);
205
+ return `${innerType} | null`;
206
+ } else if ((0, import_transactions.isClarityAbiTuple)(val)) {
207
+ const tupleDefs = [];
208
+ val.tuple.forEach(({ name, type }) => {
209
+ const innerType = jsTypeFromAbiType(type);
210
+ tupleDefs.push(`"${name}": ${innerType}`);
211
+ });
212
+ return `{
213
+ ${tupleDefs.join(";\n ")}
214
+ }`;
215
+ } else if ((0, import_transactions.isClarityAbiList)(val)) {
216
+ const innerType = jsTypeFromAbiType(val.list.type);
217
+ return `${innerType}[]`;
218
+ } else if ((0, import_transactions.isClarityAbiStringAscii)(val)) {
219
+ return "string";
220
+ } else if ((0, import_transactions.isClarityAbiStringUtf8)(val)) {
221
+ return "string";
222
+ } else if (val === "trait_reference") {
223
+ return "string";
224
+ } else {
225
+ throw new Error(`Unexpected Clarity ABI type: ${JSON.stringify(val)}`);
226
+ }
227
+ };
228
+ function getArgName(name) {
229
+ const camel = (0, import_core.toCamelCase)(name);
230
+ const prefix = (0, import_reserved_words.check)(camel, 6) ? "_" : "";
231
+ return `${prefix}${camel}`;
232
+ }
233
+ var accessToReturnType = {
234
+ public: "Public",
235
+ read_only: "ReadOnly",
236
+ private: "Private"
237
+ };
238
+ function makePureTypes(abi) {
239
+ let typings = "";
240
+ abi.functions.forEach((func, index) => {
241
+ let functionLine = `${(0, import_core.toCamelCase)(func.name)}: `;
242
+ const args = func.args.map((arg) => {
243
+ return `${getArgName(arg.name)}: ${jsTypeFromAbiType(arg.type, true)}`;
244
+ });
245
+ functionLine += `(${args.join(", ")}) => `;
246
+ const funcType = accessToReturnType[func.access];
247
+ functionLine += `ContractCalls.${funcType}<`;
248
+ if (func.access === "public") {
249
+ const { type } = func.outputs;
250
+ if (!(0, import_transactions.isClarityAbiResponse)(type))
251
+ throw new Error("Expected response type for public function");
252
+ const ok = jsTypeFromAbiType(type.response.ok);
253
+ const err = jsTypeFromAbiType(type.response.error);
254
+ functionLine += `${ok}, ${err}>;`;
255
+ } else {
256
+ const returnType = jsTypeFromAbiType(func.outputs.type);
257
+ functionLine += `${returnType}>;`;
258
+ }
259
+ typings += `${index === 0 ? "" : "\n"} ${functionLine}`;
260
+ });
261
+ abi.maps.forEach((map) => {
262
+ let functionLine = `${(0, import_core.toCamelCase)(map.name)}: `;
263
+ const keyType = jsTypeFromAbiType(map.key, true);
264
+ const arg = `key: ${keyType}`;
265
+ const valType = jsTypeFromAbiType(map.value);
266
+ functionLine += `(${arg}) => ContractCalls.Map<${keyType}, ${valType}>;`;
267
+ typings += `
268
+ ${functionLine}`;
269
+ });
270
+ return typings;
271
+ }
272
+
273
+ // src/generate/files.ts
274
+ var generateInterfaceFile = ({
275
+ contractName,
276
+ abi
277
+ }) => {
278
+ const variableName = (0, import_core2.toCamelCase)(contractName, true);
279
+ const _a = abi, { clarity_version } = _a, rest = __objRest(_a, ["clarity_version"]);
280
+ const abiString = JSON.stringify(rest, null, 2);
281
+ const fileContents = `import { ClarityAbi } from '@clarigen/core';
9
282
 
10
283
  // prettier-ignore
11
- export const ${r}Interface: ClarityAbi = ${i};
12
- `},mt=({contractFile:t,contractAddress:e,contractName:r})=>{let n=(0,F.toCamelCase)(r,!0),o=(0,F.toCamelCase)(r),i=`${n}Contract`,a=`${n}Interface`;return`import { pureProxy, Contract } from '@clarigen/core';
13
- import type { ${i} } from './types';
14
- import { ${a} } from './abi';
15
- export type { ${i} } from './types';
16
-
17
- export function ${o}Contract(contractAddress: string, contractName: string) {
18
- return pureProxy<${i}>({
19
- abi: ${a},
284
+ export const ${variableName}Interface: ClarityAbi = ${abiString};
285
+ `;
286
+ return fileContents;
287
+ };
288
+ var generateIndexFile = ({
289
+ contractFile,
290
+ contractAddress,
291
+ contractName
292
+ }) => {
293
+ const contractTitle = (0, import_core2.toCamelCase)(contractName, true);
294
+ const varName = (0, import_core2.toCamelCase)(contractName);
295
+ const contractType = `${contractTitle}Contract`;
296
+ const interfaceVar = `${contractTitle}Interface`;
297
+ const fileContents = `import { pureProxy, Contract } from '@clarigen/core';
298
+ import type { ${contractType} } from './types';
299
+ import { ${interfaceVar} } from './abi';
300
+ export type { ${contractType} } from './types';
301
+
302
+ export function ${varName}Contract(contractAddress: string, contractName: string) {
303
+ return pureProxy<${contractType}>({
304
+ abi: ${interfaceVar},
20
305
  contractAddress,
21
306
  contractName,
22
307
  });
23
308
  }
24
309
 
25
- export const ${o}Info: Contract<${i}> = {
26
- contract: ${o}Contract,
27
- address: '${e}',
28
- contractFile: '${t}',
29
- name: '${r}',
30
- abi: ${a},
310
+ export const ${varName}Info: Contract<${contractType}> = {
311
+ contract: ${varName}Contract,
312
+ address: '${contractAddress}',
313
+ contractFile: '${contractFile}',
314
+ name: '${contractName}',
315
+ abi: ${interfaceVar},
316
+ };
317
+ `;
318
+ return fileContents;
31
319
  };
32
- `},ut=(t,e)=>{let r=(0,F.toCamelCase)(e,!0),n=ft(t);return`import { Response, ContractCalls } from '@clarigen/core';
320
+ var generateTypesFile = (abi, contractName) => {
321
+ const name = (0, import_core2.toCamelCase)(contractName, true);
322
+ const typings = makePureTypes(abi);
323
+ const fileContents = `import { Response, ContractCalls } from '@clarigen/core';
33
324
 
34
325
  // prettier-ignore
35
- export interface ${r}Contract {
36
- ${n}
326
+ export interface ${name}Contract {
327
+ ${typings}
37
328
  }
38
- `},gt=t=>{let e=["import type { ContractInstances } from '@clarigen/core';"],r=[],n=[],o="";"accounts"in t&&(o=`
329
+ `;
330
+ return fileContents;
331
+ };
332
+ var generateProjectIndexFile = (config) => {
333
+ const imports = [
334
+ "import type { ContractInstances } from '@clarigen/core';"
335
+ ];
336
+ const exports = [];
337
+ const contractMap = [];
338
+ let accounts = "";
339
+ if ("accounts" in config) {
340
+ const accountLines = Object.keys(config.accounts).map((key) => {
341
+ const account = config.accounts[key];
342
+ return `"${key}": {
343
+ mnemonic: "${account.mnemonic}",
344
+ balance: ${account.balance.toString()}n,
345
+ address: "${account.address}",
346
+ },`;
347
+ });
348
+ accounts = `
39
349
 
40
350
  // prettier-ignore
41
351
  export const accounts = {
42
- ${Object.keys(t.accounts).map(l=>{let f=t.accounts[l];return`"${l}": {
43
- mnemonic: "${f.mnemonic}",
44
- balance: ${f.balance.toString()}n,
45
- address: "${f.address}",
46
- },`}).join(`
47
- `)}
48
- };`),t.contracts.forEach(s=>{let l=s.name,f=(0,F.toCamelCase)(l),b=`${f}Info`,A=`${(0,F.toCamelCase)(l,!0)}Contract`,C=(0,B.dirname)(s.file),$=`'./${(0,B.join)(C||".",l)}'`,c=`import { ${b} } from ${$};`;e.push(c);let u=`export type { ${A} } from ${$};`;r.push(u);let v=`${f}: ${b},`;n.push(v)});let i=`
352
+ ${accountLines.join("\n ")}
353
+ };`;
354
+ }
355
+ config.contracts.forEach((contract) => {
356
+ const contractName = contract.name;
357
+ const contractVar = (0, import_core2.toCamelCase)(contractName);
358
+ const contractInfo = `${contractVar}Info`;
359
+ const contractInterface = `${(0, import_core2.toCamelCase)(contractName, true)}Contract`;
360
+ const dirName = (0, import_path3.dirname)(contract.file);
361
+ const importPath = `'./${(0, import_path3.join)(dirName || ".", contractName)}'`;
362
+ const _import = `import { ${contractInfo} } from ${importPath};`;
363
+ imports.push(_import);
364
+ const _export = `export type { ${contractInterface} } from ${importPath};`;
365
+ exports.push(_export);
366
+ const map = `${contractVar}: ${contractInfo},`;
367
+ contractMap.push(map);
368
+ });
369
+ const contractsType = `
49
370
  export type Contracts = ContractInstances<typeof contracts>;
50
- `;return`${e.join(`
51
- `)}
52
- ${r.join(`
53
- `)}
54
- ${i}
371
+ `;
372
+ const file = `${imports.join("\n")}
373
+ ${exports.join("\n")}
374
+ ${contractsType}
375
+ export const contracts = {
376
+ ${contractMap.join("\n ")}
377
+ };${accounts}
378
+ `;
379
+ return file;
380
+ };
381
+
382
+ // src/utils.ts
383
+ var import_native_bin3 = require("@clarigen/native-bin");
384
+ var import_path7 = require("path");
385
+ var import_promises6 = require("fs/promises");
386
+
387
+ // src/docs.ts
388
+ var import_claridocs = require("@clarigen/claridocs");
389
+ var import_promises3 = require("fs/promises");
390
+ var import_path4 = require("path");
391
+ async function generateMarkdownDoc({
392
+ contractFile,
393
+ contractName,
394
+ docsPath,
395
+ abi,
396
+ dirName
397
+ }) {
398
+ const contractSrc = await (0, import_promises3.readFile)(contractFile, { encoding: "utf-8" });
399
+ const docs = (0, import_claridocs.createContractDocInfo)({ contractSrc, abi });
400
+ const folder = (0, import_path4.resolve)(process.cwd(), docsPath, dirName || ".");
401
+ const filePath = (0, import_path4.resolve)(folder, `${contractName}.md`);
402
+ const md = (0, import_claridocs.generateMarkdown)({
403
+ contract: docs,
404
+ contractFile: (0, import_path4.relative)(folder, contractFile),
405
+ contractName,
406
+ abi
407
+ });
408
+ await (0, import_promises3.mkdir)(folder, { recursive: true });
409
+ await (0, import_promises3.writeFile)(filePath, md);
410
+ }
411
+ async function generateDocsIndex(configFile) {
412
+ if (!configFile.docs)
413
+ return;
414
+ const contractLines = configFile.contracts.map((contract) => {
415
+ const fileName = contract.file.replace(".clar", ".md");
416
+ return `- [\`${contract.name}\`](${fileName})`;
417
+ });
418
+ const fileContents = `# Contracts
419
+
420
+ ${contractLines.join("\n")}
421
+ `;
422
+ const filepath = (0, import_path4.resolve)(process.cwd(), configFile.docs, "README.md");
423
+ await (0, import_promises3.writeFile)(filepath, fileContents);
424
+ }
425
+
426
+ // src/generate/single.ts
427
+ var import_core3 = require("@clarigen/core");
428
+ var import_path5 = require("path");
429
+ var import_promises4 = require("fs/promises");
430
+ var import_util = require("util");
431
+ function generateContractMeta(contract) {
432
+ const { abi } = contract;
433
+ const functionLines = [];
434
+ const _a = abi, { functions, variables, maps } = _a, rest = __objRest(_a, ["functions", "variables", "maps"]);
435
+ functions.forEach((func) => {
436
+ let functionLine = `${(0, import_core3.toCamelCase)(func.name)}: `;
437
+ const args = func.args.map((arg) => {
438
+ return `${getArgName(arg.name)}: ${jsTypeFromAbiType(arg.type, true)}`;
439
+ });
440
+ const argsTuple = `[${args.join(", ")}]`;
441
+ const funcDef = JSON.stringify(func);
442
+ functionLine += funcDef;
443
+ const retType = jsTypeFromAbiType(func.outputs.type);
444
+ functionLine += ` as TypedAbiFunction<${argsTuple}, ${retType}>`;
445
+ functionLines.push(functionLine);
446
+ });
447
+ const variableLines = contract.variables.map((v) => {
448
+ let varLine = `${(0, import_core3.toCamelCase)(v.name)}: `;
449
+ const type = jsTypeFromAbiType(v.type);
450
+ const varJSON = (0, import_util.inspect)(v, false, null, false);
451
+ varLine += `${varJSON} as TypedAbiVariable<${type}>`;
452
+ return varLine;
453
+ });
454
+ const constants2 = contract.variables.filter((v) => v.access === "constant");
455
+ const constantLines = constants2.map((constant) => {
456
+ return `"${(0, import_core3.toCamelCase)(constant.name)}": ${serialize(constant.defaultValue)}`;
457
+ });
458
+ const mapLines = maps.map((map) => {
459
+ let mapLine = `${(0, import_core3.toCamelCase)(map.name)}: `;
460
+ const keyType = jsTypeFromAbiType(map.key);
461
+ const valType = jsTypeFromAbiType(map.value);
462
+ mapLine += JSON.stringify(map);
463
+ mapLine += ` as TypedAbiMap<${keyType}, ${valType}>`;
464
+ return mapLine;
465
+ });
466
+ const otherAbi = JSON.stringify(rest);
467
+ const contractFile = (0, import_path5.relative)(process.cwd(), contract.contractFile);
468
+ return `{
469
+ ${serializeLines("functions", functionLines)}
470
+ ${serializeLines("variables", variableLines)}
471
+ ${serializeLines("maps", mapLines)}
472
+ ${serializeLines("constants", constantLines)}
473
+ ${otherAbi.slice(1, -1)},
474
+ contractName: '${contract.contractName}',
475
+ contractFile: '${contractFile}',
476
+ }`;
477
+ }
478
+ async function generateSingleFile(config, contracts) {
479
+ const contractDefs = contracts.map((contract) => {
480
+ const meta = generateContractMeta(contract);
481
+ const keyName = (0, import_core3.toCamelCase)(contract.contractName);
482
+ return `${keyName}: ${meta}`;
483
+ });
484
+ const types = await getSingleTypes();
485
+ const accounts = generateAccounts(config);
486
+ const file = `
487
+ ${types}
488
+
55
489
  export const contracts = {
56
- ${n.join(`
57
- `)}
58
- };${o}
59
- `};var K=require("@clarigen/native-bin"),g=require("path"),Tt=require("fs/promises");var J=require("@clarigen/claridocs"),T=require("fs/promises"),P=require("path");async function Ct({contractFile:t,contractName:e,docsPath:r,abi:n,dirName:o}){let i=await(0,T.readFile)(t,{encoding:"utf-8"}),a=(0,J.createContractDocInfo)({contractSrc:i,abi:n}),s=(0,P.resolve)(process.cwd(),r,o||"."),l=(0,P.resolve)(s,`${e}.md`),f=(0,J.generateMarkdown)({contract:a,contractFile:(0,P.relative)(s,t),contractName:e,abi:n});await(0,T.mkdir)(s,{recursive:!0}),await(0,T.writeFile)(l,f)}async function yt(t){if(!t.docs)return;let r=`# Contracts
60
-
61
- ${t.contracts.map(o=>{let i=o.file.replace(".clar",".md");return`- [\`${o.name}\`](${i})`}).join(`
62
- `)}
63
- `,n=(0,P.resolve)(process.cwd(),t.docs,"README.md");await(0,T.writeFile)(n,r)}var N=require("@clarigen/core");var U=require("path"),dt=require("fs/promises"),W=require("util");function zt(t){let{abi:e}=t,r=[],$=e,{functions:n,variables:o,maps:i}=$,a=V($,["functions","variables","maps"]);n.forEach(c=>{let u=`${(0,N.toCamelCase)(c.name)}: `,k=`[${c.args.map(tt=>`${Z(tt.name)}: ${p(tt.type,!0)}`).join(", ")}]`;u+=JSON.stringify(c);let Nt=p(c.outputs.type);u+=` as TypedAbiFunction<${k}, ${Nt}>`,r.push(u)});let s=t.variables.map(c=>{let u=`${(0,N.toCamelCase)(c.name)}: `,v=p(c.type);return u+=`${(0,W.inspect)(c,!1,null,!1)} as TypedAbiVariable<${v}>`,u}),f=t.variables.filter(c=>c.access==="constant").map(c=>`"${(0,N.toCamelCase)(c.name)}": ${qt(c.defaultValue)}`),b=i.map(c=>{let u=`${(0,N.toCamelCase)(c.name)}: `,v=p(c.key),k=p(c.value);return u+=JSON.stringify(c),u+=` as TypedAbiMap<${v}, ${k}>`,u}),A=JSON.stringify(a),C=(0,U.relative)(process.cwd(),t.contractFile);return`{
64
- ${R("functions",r)}
65
- ${R("variables",s)}
66
- ${R("maps",b)}
67
- ${R("constants",f)}
68
- ${A.slice(1,-1)},
69
- contractName: '${t.contractName}',
70
- contractFile: '${C}',
71
- }`}async function $t(t,e){let r=e.map(a=>{let s=zt(a);return`${(0,N.toCamelCase)(a.contractName)}: ${s}`}),n=await Ht(),o=Kt(t);return`
72
- ${n}
73
-
74
- export const contracts: Record<string, TypedAbi> = {
75
- ${r.join(`,
76
- `)}
490
+ ${contractDefs.join(",\n")}
77
491
  } as const;
78
492
 
79
- ${o}
80
- `}function Kt(t){let e="";return"accounts"in t&&(e=`export const accounts = {
81
- ${Object.keys(t.accounts).map(n=>{let o=t.accounts[n];return`"${n}": {
82
- mnemonic: "${o.mnemonic}",
83
- balance: ${o.balance.toString()}n,
84
- address: "${o.address}",
85
- },`}).join(`
86
- `)}
87
- } as const;`),e}Uint8Array.prototype[W.inspect.custom]=function(){return`Uint8Array.from([${this.join(",")}])`};function qt(t){return(0,W.inspect)(t,!1,null,!1)}function R(t,e){return`"${t}": {
88
- ${e.join(`,
89
- `)}
90
- },`}async function Ht(){let t=(0,U.resolve)(__dirname,"../../../core/src/abi-types.ts");return await(0,dt.readFile)(t,{encoding:"utf-8"})}var bt=require("fs/promises"),xt=require("path"),z=require("prettier"),Qt={printWidth:80,semi:!0,singleQuote:!0,trailingComma:"es5"};async function Xt(){try{let t=await(0,z.resolveConfig)(process.cwd());if(t)return t}catch{}return Qt}async function Yt(t,e){try{let r=(0,xt.basename)(e),n=await Xt();return(0,z.format)(t,x(y({},n),{filepath:r}))}catch{}return t}async function j(t,e){let r=await Yt(e,t);await(0,bt.writeFile)(t,r)}var wt=require("@clarigen/core"),At=require("@clarigen/native-bin"),ht=require("micro-stacks/clarity");async function Ft({abi:t,contractIdentifier:e,provider:r}){let n=t.variables.map(i=>Zt({variable:i,provider:r,contractIdentifier:e}));return await Promise.all(n)}async function Zt({contractIdentifier:t,variable:e,provider:r}){let n=Gt(e),o=await(0,At.evalRaw)({contractAddress:t,code:n,provider:r}),i=(0,ht.hexToCV)(o.output_serialized),a=(0,wt.cvToValue)(i,!0);return x(y({},e),{defaultValue:a})}function Gt(t){let{access:e}=t;return e==="variable"?`(var-get ${t.name})`:t.name}var te=async({contractFile:t,outputFolder:e,provider:r,contractAddress:n,dirName:o,contractName:i,docsPath:a})=>{let s=(0,g.resolve)(process.cwd(),t),l=`${n}.${i}`,f=await(0,K.deployContract)({contractIdentifier:l,contractFilePath:s,provider:r}),b=await Ft({abi:f,contractIdentifier:l,provider:r}),A=ut(f,i),C=mt({contractFile:(0,g.relative)(process.cwd(),s),contractAddress:n,contractName:i}),$=pt({contractName:i,abi:f});typeof a<"u"&&await Ct({contractFile:s,contractName:i,abi:f,docsPath:a,dirName:o});let c=(0,g.resolve)(e,o||".",i);return await(0,Tt.mkdir)(c,{recursive:!0}),await j((0,g.resolve)(c,"abi.ts"),$),await j((0,g.resolve)(c,"index.ts"),C),await j((0,g.resolve)(c,"types.ts"),A),{abi:f,contractFile:s,contractName:i,dirName:o,contractAddress:n,variables:b}},q=async t=>{let e=await M(t),{contractsDir:r,outputDir:n,contracts:o}=e,i=(0,g.resolve)(t,n),a=await(0,K.createClarityBin)(),s=[];for(let C of o){let $=(0,g.resolve)(t,r,C.file),c=(0,g.dirname)(C.file),u=await te({contractFile:$,outputFolder:i,provider:a,contractAddress:C.address,dirName:c,contractName:C.name,docsPath:e.docs});s.push(u)}let l=gt(e);await yt(e);let f=(0,g.resolve)(i,"index.ts");await j(f,l);let b=await $t(e,s),A=(0,g.resolve)(i,"single.ts");await j(A,b)};var vt=require("chokidar"),Pt=require("path"),I=require("chalk"),ee=require("ora"),G=class extends E.Command{async run(){let{flags:e}=this.parse(G),r=process.cwd();if(e.watch){let n=ee("Generating files").start(),{contractsDir:o}=await M(r),i=(0,vt.watch)([o],{cwd:r});try{await q(r),n.succeed("Finished generating files. Watching for changes.")}catch(a){n.fail(`Error generating files.
91
- ${a.message}`)}i.on("change",async a=>{let s=(0,Pt.basename)(a);n.clear(),n.start(`Change detected for ${(0,I.green)(s)}, generating.`);try{await q(r),n.succeed(`Finished generating files for ${(0,I.green)(s)}. Watching for changes.`)}catch(l){let f=l.message;n.fail(`Error after saving ${(0,I.red)(s)}.
92
- ${f}`)}}),process.on("SIGINT",async()=>{await i.close(),process.exit()})}else await q(r)}},w=G;w.description="Generate project files",w.strict=!0,w.hidden=!1,w.flags={help:E.flags.help({char:"h"}),watch:E.flags.boolean({char:"w",description:"Watch for changes to your contracts"})},w.args=[];0&&(module.exports={Generate});
493
+ ${accounts}
494
+ `;
495
+ return file;
496
+ }
497
+ function generateAccounts(config) {
498
+ let accounts = "";
499
+ if ("accounts" in config) {
500
+ const accountLines = Object.keys(config.accounts).map((key) => {
501
+ const account = config.accounts[key];
502
+ return `"${key}": {
503
+ mnemonic: "${account.mnemonic}",
504
+ balance: ${account.balance.toString()}n,
505
+ address: "${account.address}",
506
+ },`;
507
+ });
508
+ accounts = `export const accounts = {
509
+ ${accountLines.join("\n ")}
510
+ } as const;`;
511
+ }
512
+ return accounts;
513
+ }
514
+ Uint8Array.prototype[import_util.inspect.custom] = function() {
515
+ return `Uint8Array.from([${this.join(",")}])`;
516
+ };
517
+ function serialize(obj) {
518
+ return (0, import_util.inspect)(obj, {
519
+ showHidden: false,
520
+ maxArrayLength: null,
521
+ maxStringLength: null,
522
+ depth: null,
523
+ colors: false
524
+ });
525
+ }
526
+ function serializeLines(key, lines) {
527
+ return `"${key}": {
528
+ ${lines.join(",\n ")}
529
+ },`;
530
+ }
531
+ async function getSingleTypes() {
532
+ const typesPath = (0, import_path5.resolve)(__dirname, "../../dist/abi-types.ts.txt");
533
+ const typesFile = await (0, import_promises4.readFile)(typesPath, { encoding: "utf-8" });
534
+ return typesFile;
535
+ }
536
+
537
+ // src/writer.ts
538
+ var import_promises5 = require("fs/promises");
539
+ var import_path6 = require("path");
540
+ var import_prettier = require("prettier");
541
+ var defaultPrettierConfig = {
542
+ printWidth: 80,
543
+ semi: true,
544
+ singleQuote: true,
545
+ trailingComma: "es5"
546
+ };
547
+ async function resolvePrettierConfig() {
548
+ try {
549
+ const local = await (0, import_prettier.resolveConfig)(process.cwd());
550
+ if (local)
551
+ return local;
552
+ } catch (error) {
553
+ }
554
+ return defaultPrettierConfig;
555
+ }
556
+ async function formatFile(contents, path) {
557
+ try {
558
+ const fileName = (0, import_path6.basename)(path);
559
+ const config = await resolvePrettierConfig();
560
+ const formatted = (0, import_prettier.format)(contents, __spreadProps(__spreadValues({}, config), {
561
+ filepath: fileName
562
+ }));
563
+ return formatted;
564
+ } catch (error) {
565
+ }
566
+ return contents;
567
+ }
568
+ async function writeFile2(path, contents) {
569
+ const formatted = await formatFile(contents, path);
570
+ await (0, import_promises5.writeFile)(path, formatted);
571
+ }
572
+
573
+ // src/generate/vars.ts
574
+ var import_core4 = require("@clarigen/core");
575
+ var import_native_bin2 = require("@clarigen/native-bin");
576
+ var import_clarity = require("micro-stacks/clarity");
577
+ async function getVariables({
578
+ abi,
579
+ contractIdentifier,
580
+ provider
581
+ }) {
582
+ const variableTransforms = abi.variables.map((variable) => {
583
+ return evalVariable({
584
+ variable,
585
+ provider,
586
+ contractIdentifier
587
+ });
588
+ });
589
+ const variables = await Promise.all(variableTransforms);
590
+ return variables;
591
+ }
592
+ async function evalVariable({
593
+ contractIdentifier,
594
+ variable,
595
+ provider
596
+ }) {
597
+ const code = getEvalCode(variable);
598
+ const result = await (0, import_native_bin2.evalRaw)({
599
+ contractAddress: contractIdentifier,
600
+ code,
601
+ provider
602
+ });
603
+ const resultCV = (0, import_clarity.hexToCV)(result.output_serialized);
604
+ const value = (0, import_core4.cvToValue)(resultCV, true);
605
+ return __spreadProps(__spreadValues({}, variable), {
606
+ defaultValue: value
607
+ });
608
+ }
609
+ function getEvalCode(variable) {
610
+ const { access: access2 } = variable;
611
+ if (access2 === "variable") {
612
+ return `(var-get ${variable.name})`;
613
+ }
614
+ return variable.name;
615
+ }
616
+
617
+ // src/utils.ts
618
+ var generateFilesForContract = async ({
619
+ contractFile: _contractFile,
620
+ outputFolder,
621
+ provider,
622
+ contractAddress,
623
+ dirName,
624
+ contractName,
625
+ docsPath
626
+ }) => {
627
+ const contractFile = (0, import_path7.resolve)(process.cwd(), _contractFile);
628
+ const contractIdentifier = `${contractAddress}.${contractName}`;
629
+ const abi = await (0, import_native_bin3.deployContract)({
630
+ contractIdentifier,
631
+ contractFilePath: contractFile,
632
+ provider
633
+ });
634
+ const variables = await getVariables({
635
+ abi,
636
+ contractIdentifier,
637
+ provider
638
+ });
639
+ const typesFile = generateTypesFile(abi, contractName);
640
+ const indexFile = generateIndexFile({
641
+ contractFile: (0, import_path7.relative)(process.cwd(), contractFile),
642
+ contractAddress,
643
+ contractName
644
+ });
645
+ const abiFile = generateInterfaceFile({ contractName, abi });
646
+ if (typeof docsPath !== "undefined") {
647
+ await generateMarkdownDoc({
648
+ contractFile,
649
+ contractName,
650
+ abi,
651
+ docsPath,
652
+ dirName
653
+ });
654
+ }
655
+ const outputPath = (0, import_path7.resolve)(outputFolder, dirName || ".", contractName);
656
+ await (0, import_promises6.mkdir)(outputPath, { recursive: true });
657
+ await writeFile2((0, import_path7.resolve)(outputPath, "abi.ts"), abiFile);
658
+ await writeFile2((0, import_path7.resolve)(outputPath, "index.ts"), indexFile);
659
+ await writeFile2((0, import_path7.resolve)(outputPath, "types.ts"), typesFile);
660
+ return {
661
+ abi,
662
+ contractFile,
663
+ contractName,
664
+ dirName,
665
+ contractAddress,
666
+ variables
667
+ };
668
+ };
669
+ var generateProject = async (projectPath) => {
670
+ const configFile = await getProjectConfig(projectPath);
671
+ const { contractsDir, outputDir, contracts } = configFile;
672
+ const outputFolder = (0, import_path7.resolve)(projectPath, outputDir);
673
+ const provider = await (0, import_native_bin3.createClarityBin)();
674
+ const metas = [];
675
+ for (const contract of contracts) {
676
+ const contractFile = (0, import_path7.resolve)(projectPath, contractsDir, contract.file);
677
+ const dirName = (0, import_path7.dirname)(contract.file);
678
+ const meta = await generateFilesForContract({
679
+ contractFile,
680
+ outputFolder,
681
+ provider,
682
+ contractAddress: contract.address,
683
+ dirName,
684
+ contractName: contract.name,
685
+ docsPath: configFile.docs
686
+ });
687
+ metas.push(meta);
688
+ }
689
+ const indexFile = generateProjectIndexFile(configFile);
690
+ await generateDocsIndex(configFile);
691
+ const indexPath = (0, import_path7.resolve)(outputFolder, "index.ts");
692
+ await writeFile2(indexPath, indexFile);
693
+ const singleFile = await generateSingleFile(configFile, metas);
694
+ const singlePath = (0, import_path7.resolve)(outputFolder, "single.ts");
695
+ await writeFile2(singlePath, singleFile);
696
+ };
697
+
698
+ // src/commands/index.ts
699
+ var import_chokidar = require("chokidar");
700
+ var import_path8 = require("path");
701
+ var import_chalk = require("chalk");
702
+ var ora = require("ora");
703
+ var _Generate = class extends import_command2.Command {
704
+ async run() {
705
+ const { flags: flags2 } = this.parse(_Generate);
706
+ const cwd = process.cwd();
707
+ if (flags2.watch) {
708
+ const spinner = ora("Generating files").start();
709
+ const { contractsDir } = await getProjectConfig(cwd);
710
+ const watcher = (0, import_chokidar.watch)([contractsDir], {
711
+ cwd
712
+ });
713
+ try {
714
+ await generateProject(cwd);
715
+ spinner.succeed(`Finished generating files. Watching for changes.`);
716
+ } catch (error) {
717
+ spinner.fail(`Error generating files.
718
+ ${error.message}`);
719
+ }
720
+ watcher.on("change", async (path) => {
721
+ const file = (0, import_path8.basename)(path);
722
+ spinner.clear();
723
+ spinner.start(`Change detected for ${(0, import_chalk.green)(file)}, generating.`);
724
+ try {
725
+ await generateProject(cwd);
726
+ spinner.succeed(`Finished generating files for ${(0, import_chalk.green)(file)}. Watching for changes.`);
727
+ } catch (error) {
728
+ const msg = error.message;
729
+ spinner.fail(`Error after saving ${(0, import_chalk.red)(file)}.
730
+ ${msg}`);
731
+ }
732
+ });
733
+ process.on("SIGINT", async () => {
734
+ await watcher.close();
735
+ process.exit();
736
+ });
737
+ } else {
738
+ await generateProject(cwd);
739
+ }
740
+ }
741
+ };
742
+ var Generate = _Generate;
743
+ Generate.description = `Generate project files`;
744
+ Generate.strict = true;
745
+ Generate.hidden = false;
746
+ Generate.flags = {
747
+ help: import_command2.flags.help({ char: "h" }),
748
+ watch: import_command2.flags.boolean({
749
+ char: "w",
750
+ description: "Watch for changes to your contracts"
751
+ })
752
+ };
753
+ Generate.args = [];
754
+ // Annotate the CommonJS export names for ESM import in node:
755
+ 0 && (module.exports = {
756
+ Generate
757
+ });