@clarigen/cli 1.0.0-next.15 → 1.0.0-next.18

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