@clarigen/cli 1.0.0-next.17 → 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,ut=Object.defineProperties,mt=Object.getOwnPropertyDescriptor,Ct=Object.getOwnPropertyDescriptors,dt=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,b=(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},I=(t,r)=>ut(t,Ct(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 yt=(t,r)=>{for(var n in r)E(t,n,{get:r[n],enumerable:!0})},$t=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of dt(r))!_.call(t,o)&&o!==n&&E(t,o,{get:()=>r[o],enumerable:!(e=mt(r,o))||e.enumerable});return t};var xt=t=>$t(E({},"__esModule",{value:!0}),t);var Nt={};yt(Nt,{Generate:()=>C});module.exports=xt(Nt);var A=require("@oclif/command");var G=require("@clarigen/native-bin"),$=require("@clarigen/core"),v=require("path");var It=require("@oclif/command");var y=require("path"),k=require("fs/promises"),Y=require("fs");var B=require("@ltd/j-toml"),L=require("path"),R=require("fs/promises"),j=require("micro-stacks/wallet-sdk"),K=require("toposort"),q=require("micro-stacks/crypto");async function wt(t){let r=(0,L.resolve)(t,"settings","Devnet.toml"),n=await(0,R.readFile)(r,{encoding:"utf-8"});return(0,B.parse)(n,1,`
2
- `,!0,{longer:!0})}async function ht(t){let r=(0,L.resolve)(t,"Clarinet.toml"),n=await(0,R.readFile)(r,{encoding:"utf-8"});return(0,B.parse)(n,1,`
3
- `,!0)}async function H(t,r){let n=await ht(t),e=r.deployer.address;return bt(n.contracts).map(c=>({file:n.contracts[c].path.replace(/^contracts\//,""),address:e,name:c}))}function bt(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 wt(t),n=await Promise.all(Object.entries(r.accounts).map(async([o,i])=>{let c=await(0,j.generateWallet)(i.mnemonic,"password"),[s]=c.accounts,a=(0,j.getStxAddressFromAccount)(s,q.StacksNetworkVersion.testnetP2PKH);return[o,I(b({},i),{address:a})]}));return Object.fromEntries(n)}var X={outputDir:"src/clarigen",clarinet:"."};function Ft(t){return(0,y.resolve)(t,"clarigen.config.json")}async function At(t){try{return await(0,k.access)(t,Y.constants.R_OK),!0}catch{return!1}}async function Pt(t){let r=Ft(t);if(await At(r)){let e=await(0,k.readFile)(r,{encoding:"utf-8"}),o=JSON.parse(e);return b(b({},X),o)}return X}async function N(t){let r=await Pt(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 I(b({},r),{contracts:o,contractsDir:i,accounts:e,clarinet:r.clarinet||"."})}var l=require("micro-stacks/transactions"),D=require("@clarigen/core"),Z=require("reserved-words"),g=(t,r=!1)=>{if((0,l.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,l.isClarityAbiBuffer)(t))return"Uint8Array";if((0,l.isClarityAbiResponse)(t)){let n=g(t.response.ok),e=g(t.response.error);return`Response<${n}, ${e}>`}else{if((0,l.isClarityAbiOptional)(t))return`${g(t.optional)} | null`;if((0,l.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,l.isClarityAbiList)(t))return`${g(t.list.type)}[]`;if((0,l.isClarityAbiStringAscii)(t))return"string";if((0,l.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,D.toCamelCase)(t);return`${(0,Z.check)(r,6)?"_":""}${r}`}var Et={public:"Public",read_only:"ReadOnly",private:"Private"};function z(t){let r="";return t.functions.forEach((n,e)=>{let o=`${(0,D.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,l.isClarityAbiResponse)(s))throw new Error("Expected response type for public function");let a=g(s.response.ok),f=g(s.response.error);o+=`${a}, ${f}>;`}else o+=`${g(n.outputs.type)}>;`;r+=`${e===0?"":`
7
- `} ${o}`}),t.maps.forEach(n=>{let e=`${(0,D.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,f]=s.split(`
13
- Near:
14
- `),u="",m=/start_line: (\d+),/.exec(f);throw m&&(u=m[1]),new Error(`Error on ${r}:
15
- ${a}
16
- ${u?`Near line ${u}`:""}
17
- Raw trace:
18
- ${f}
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,42 +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 { Response, 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 f=t.accounts[a];return`"${a}": {
42
+ ${Object.keys(t.accounts).map(l=>{let f=t.accounts[l];return`"${l}": {
56
43
  mnemonic: "${f.mnemonic}",
57
44
  balance: ${f.balance.toString()}n,
58
45
  address: "${f.address}",
59
46
  },`}).join(`
60
47
  `)}
61
- };`),t.contracts.forEach(s=>{let a=s.name,f=(0,$.toCamelCase)(a),u=`${f}Info`,h=`${(0,$.toCamelCase)(a,!0)}Contract`,m=(0,v.dirname)(s.file),M=`'./${(0,v.join)(m||".",a)}'`,lt=`import { ${u} } from ${M};`;r.push(lt);let pt=`export type { ${h} } from ${M};`;n.push(pt);let gt=`${f}: ${u},`;e.push(gt)});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 ct=require("@clarigen/native-bin"),p=require("path"),w=require("fs/promises");var S=require("@clarigen/claridocs"),x=require("fs/promises"),F=require("path");async function it({contractFile:t,contractName:r,docsPath:n,abi:e,dirName:o}){let i=await(0,x.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`),f=(0,S.generateMarkdown)({contract:c,contractFile:(0,F.relative)(s,t),contractName:r,abi:e});await(0,x.mkdir)(s,{recursive:!0}),await(0,x.writeFile)(a,f)}async function st(t){if(!t.docs)return;let n=`# Contracts
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
73
60
 
74
61
  ${t.contracts.map(o=>{let i=o.file.replace(".clar",".md");return`- [\`${o.name}\`](${i})`}).join(`
75
62
  `)}
76
- `,e=(0,F.resolve)(process.cwd(),t.docs,"README.md");await(0,x.writeFile)(e,n)}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}),f=et(a,i),u=nt({contractFile:(0,p.relative)(process.cwd(),s),contractAddress:e,contractName:i}),h=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,w.mkdir)(m,{recursive:!0}),await(0,w.writeFile)((0,p.resolve)(m,"abi.ts"),h),await(0,w.writeFile)((0,p.resolve)(m,"index.ts"),u),await(0,w.writeFile)((0,p.resolve)(m,"types.ts"),f)},O=async t=>{let r=await N(t),{contractsDir:n,outputDir:e,contracts:o}=r,i=(0,p.resolve)(t,e),c=await(0,ct.createClarityBin)();for(let f of o){let u=(0,p.resolve)(t,n,f.file),h=(0,p.dirname)(f.file);await jt({contractFile:u,outputFolder:i,provider:c,contractAddress:f.address,dirName:h,contractName:f.name,docsPath:r.docs})}let s=ot(r);await st(r);let a=(0,p.resolve)(i,"index.ts");await(0,w.writeFile)(a,s)};var at=require("chokidar"),ft=require("path"),P=require("chalk"),kt=require("ora"),J=class extends A.Command{async run(){let{flags:r}=this.parse(J),n=process.cwd();if(r.watch){let e=kt("Generating files").start(),{contractsDir:o}=await N(n),i=(0,at.watch)([o],{cwd:n});try{await O(n),e.succeed("Finished generating files. Watching for changes.")}catch(c){e.fail(`Error generating files.
77
- ${c.message}`)}i.on("change",async c=>{let s=(0,ft.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 f=a.message;e.fail(`Error after saving ${(0,P.red)(s)}.
78
- ${f}`)}}),process.on("SIGINT",async()=>{await i.close(),process.exit()})}else await O(n)}},C=J;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});
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 rt=Object.defineProperty,nt=Object.defineProperties;var et=Object.getOwnPropertyDescriptors;var w=Object.getOwnPropertySymbols;var k=Object.prototype.hasOwnProperty,N=Object.prototype.propertyIsEnumerable;var j=(t,n,r)=>n in t?rt(t,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[n]=r,$=(t,n)=>{for(var r in n||(n={}))k.call(n,r)&&j(t,r,n[r]);if(w)for(var r of w(n))N.call(n,r)&&j(t,r,n[r]);return t},h=(t,n)=>nt(t,et(n));var ot=(t=>typeof require!="undefined"?require:typeof Proxy!="undefined"?new Proxy(t,{get:(n,r)=>(typeof require!="undefined"?require:n)[r]}):t)(function(t){if(typeof require!="undefined")return require.apply(this,arguments);throw new Error('Dynamic require of "'+t+'" is not supported')});var D=(t,n)=>{var r={};for(var e in t)k.call(t,e)&&n.indexOf(e)<0&&(r[e]=t[e]);if(t!=null&&w)for(var e of w(t))n.indexOf(e)<0&&N.call(t,e)&&(r[e]=t[e]);return r};import{Command as Wt,flags as Y}from"@oclif/command";import{hasStdErr as kt}from"@clarigen/native-bin";import{toCamelCase as x}from"@clarigen/core";import{dirname as Nt,join as Dt}from"path";import{run as Cr}from"@oclif/command";import{resolve as R,join as gt,relative as ut}from"path";import{readFile as mt,access as Ct}from"fs/promises";import{constants as dt}from"fs";import{parse as v}from"@ltd/j-toml";import{resolve as S}from"path";import{readFile as O}from"fs/promises";import{generateWallet as it,getStxAddressFromAccount as st}from"micro-stacks/wallet-sdk";import{array as ct}from"toposort";import{StacksNetworkVersion as at}from"micro-stacks/crypto";async function ft(t){let n=S(t,"settings","Devnet.toml"),r=await O(n,{encoding:"utf-8"});return v(r,1,`
2
- `,!0,{longer:!0})}async function lt(t){let n=S(t,"Clarinet.toml"),r=await O(n,{encoding:"utf-8"});return v(r,1,`
3
- `,!0)}async function _(t,n){let r=await lt(t),e=n.deployer.address;return pt(r.contracts).map(c=>({file:r.contracts[c].path.replace(/^contracts\//,""),address:e,name:c}))}function pt(t){let n=[],r=[];return Object.entries(t).forEach(([o,i])=>{r.push(o),i.depends_on.forEach(c=>n.push([o,c]))}),ct(r,n).reverse()}async function B(t){let n=await ft(t),r=await Promise.all(Object.entries(n.accounts).map(async([o,i])=>{let c=await it(i.mnemonic,"password"),[s]=c.accounts,a=st(s,at.testnetP2PKH);return[o,h($({},i),{address:a})]}));return Object.fromEntries(r)}var L={outputDir:"src/clarigen",clarinet:"."};function yt(t){return R(t,"clarigen.config.json")}async function $t(t){try{return await Ct(t,dt.R_OK),!0}catch{return!1}}async function xt(t){let n=yt(t);if(await $t(n)){let e=await mt(n,{encoding:"utf-8"}),o=JSON.parse(e);return $($({},L),o)}return L}async function b(t){let n=await xt(t),r=R(t,n.clarinet||"."),e=await B(r),o=await _(r,e),i=ut(process.cwd(),gt(n.clarinet,"contracts"));return h($({},n),{contracts:o,contractsDir:i,accounts:e,clarinet:n.clarinet||"."})}import{isClarityAbiBuffer as wt,isClarityAbiList as ht,isClarityAbiOptional as bt,isClarityAbiPrimitive as Ft,isClarityAbiResponse as J,isClarityAbiStringAscii as At,isClarityAbiStringUtf8 as Pt,isClarityAbiTuple as Tt}from"micro-stacks/transactions";import{toCamelCase as P}from"@clarigen/core";import{check as Et}from"reserved-words";var l=(t,n=!1)=>{if(Ft(t)){if(t==="uint128")return n?"number | bigint":"bigint";if(t==="int128")return n?"number | bigint":"bigint";if(t==="bool")return"boolean";if(t==="principal")return"string";if(t==="none")return"null";if(t==="trait_reference")return"string";throw new Error(`Unexpected Clarity ABI type primitive: ${JSON.stringify(t)}`)}else{if(wt(t))return"Uint8Array";if(J(t)){let r=l(t.response.ok),e=l(t.response.error);return`Response<${r}, ${e}>`}else{if(bt(t))return`${l(t.optional)} | null`;if(Tt(t)){let r=[];return t.tuple.forEach(({name:e,type:o})=>{let i=l(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(ht(t))return`${l(t.list.type)}[]`;if(At(t))return"string";if(Pt(t))return"string";if(t==="trait_reference")return"string";throw new Error(`Unexpected Clarity ABI type: ${JSON.stringify(t)}`)}}}};function It(t){let n=P(t);return`${Et(n,6)?"_":""}${n}`}var jt={public:"Public",read_only:"ReadOnly",private:"Private"};function M(t){let n="";return t.functions.forEach((r,e)=>{let o=`${P(r.name)}: `;if(o+=`(${r.args.map(s=>`${It(s.name)}: ${l(s.type,!0)}`).join(", ")}) => `,o+=`ContractCalls.${jt[r.access]}<`,r.access==="public"){let{type:s}=r.outputs;if(!J(s))throw new Error("Expected response type for public function");let a=l(s.response.ok),f=l(s.response.error);o+=`${a}, ${f}>;`}else o+=`${l(r.outputs.type)}>;`;n+=`${e===0?"":`
7
- `} ${o}`}),t.maps.forEach(r=>{let e=`${P(r.name)}: `,o=l(r.key,!0),i=`key: ${o}`,c=l(r.value);e+=`(${i}) => ContractCalls.Map<${o}, ${c}>;`,n+=`
8
- ${e}`}),n}var U=async({provider:t,contractFile:n,contractAddress:r,contractName:e})=>{let o=await t.runCommand(["launch",`${r}.${e}`,n,t.dbFilePath,"--output_analysis","--costs","--assets"]);if(kt(o.stderr))throw new Error(`Error on ${n}:
9
- ${o.stderr}
10
- `);let i=JSON.parse(o.stdout);if(i.error){let{initialization:s}=i.error;if(s!=null&&s.includes(`
11
- Near:
12
- `)){let[a,f]=s.split(`
13
- Near:
14
- `),p="",g=/start_line: (\d+),/.exec(f);throw g&&(p=g[1]),new Error(`Error on ${n}:
15
- ${a}
16
- ${p?`Near line ${p}`:""}
17
- Raw trace:
18
- ${f}
19
- `)}throw new Error(`Error on ${n}:
20
- ${JSON.stringify(i.error,null,2)}
21
- `)}return i.analysis},W=({contractName:t,abi:n})=>{let r=x(t,!0),s=n,{clarity_version:e}=s,o=D(s,["clarity_version"]),i=JSON.stringify(o,null,2);return`import { ClarityAbi } from '@clarigen/core';
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
- `},V=({contractFile:t,contractAddress:n,contractName:r})=>{let e=x(r,!0),o=x(r),i=`${e}Contract`,c=`${e}Interface`;return`import { pureProxy, Contract } from '@clarigen/core';
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,42 +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
- `},K=(t,n)=>{let r=x(n,!0),e=M(t);return`import { Response, 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
- `},q=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 f=t.accounts[a];return`"${a}": {
56
- mnemonic: "${f.mnemonic}",
57
- balance: ${f.balance.toString()}n,
58
- address: "${f.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,f=x(a),p=`${f}Info`,y=`${x(a,!0)}Contract`,g=Nt(s.file),I=`'./${Dt(g||".",a)}'`,z=`import { ${p} } from ${I};`;n.push(z);let G=`export type { ${y} } from ${I};`;r.push(G);let tt=`${f}: ${p},`;e.push(tt)});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 Lt}from"@clarigen/native-bin";import{resolve as u,relative as Rt,dirname as Jt}from"path";import{mkdir as Mt,writeFile as F}from"fs/promises";import{createContractDocInfo as vt,generateMarkdown as St}from"@clarigen/claridocs";import{mkdir as Ot,readFile as _t,writeFile as H}from"fs/promises";import{relative as Bt,resolve as T}from"path";async function Q({contractFile:t,contractName:n,docsPath:r,abi:e,dirName:o}){let i=await _t(t,{encoding:"utf-8"}),c=vt({contractSrc:i,abi:e}),s=T(process.cwd(),r,o||"."),a=T(s,`${n}.md`),f=St({contract:c,contractFile:Bt(s,t),contractName:n,abi:e});await Ot(s,{recursive:!0}),await H(a,f)}async function X(t){if(!t.docs)return;let r=`# Contracts
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
73
60
 
74
61
  ${t.contracts.map(o=>{let i=o.file.replace(".clar",".md");return`- [\`${o.name}\`](${i})`}).join(`
75
62
  `)}
76
- `,e=T(process.cwd(),t.docs,"README.md");await H(e,r)}var Ut=async({contractFile:t,outputFolder:n,provider:r,contractAddress:e,dirName:o,contractName:i,docsPath:c})=>{let s=u(process.cwd(),t),a=await U({contractFile:s,provider:r,contractAddress:e,contractName:i}),f=K(a,i),p=V({contractFile:Rt(process.cwd(),s),contractAddress:e,contractName:i}),y=W({contractName:i,abi:a});typeof c<"u"&&await Q({contractFile:s,contractName:i,abi:a,docsPath:c,dirName:o});let g=u(n,o||".",i);await Mt(g,{recursive:!0}),await F(u(g,"abi.ts"),y),await F(u(g,"index.ts"),p),await F(u(g,"types.ts"),f)},A=async t=>{let n=await b(t),{contractsDir:r,outputDir:e,contracts:o}=n,i=u(t,e),c=await Lt();for(let f of o){let p=u(t,r,f.file),y=Jt(f.file);await Ut({contractFile:p,outputFolder:i,provider:c,contractAddress:f.address,dirName:y,contractName:f.name,docsPath:n.docs})}let s=q(n);await X(n);let a=u(i,"index.ts");await F(a,s)};import{watch as Vt}from"chokidar";import{basename as Kt}from"path";import{red as qt,green as Z}from"chalk";var Ht=ot("ora"),E=class extends Wt{async run(){let{flags:n}=this.parse(E),r=process.cwd();if(n.watch){let e=Ht("Generating files").start(),{contractsDir:o}=await b(r),i=Vt([o],{cwd:r});try{await A(r),e.succeed("Finished generating files. Watching for changes.")}catch(c){e.fail(`Error generating files.
77
- ${c.message}`)}i.on("change",async c=>{let s=Kt(c);e.clear(),e.start(`Change detected for ${Z(s)}, generating.`);try{await A(r),e.succeed(`Finished generating files for ${Z(s)}. Watching for changes.`)}catch(a){let f=a.message;e.fail(`Error after saving ${qt(s)}.
78
- ${f}`)}}),process.on("SIGINT",async()=>{await i.close(),process.exit()})}else await A(r)}},d=E;d.description="Generate project files",d.strict=!0,d.hidden=!1,d.flags={help:Y.help({char:"h"}),watch:Y.boolean({char:"w",description:"Watch for changes to your contracts"})},d.args=[];export{d as Generate};
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 I=Object.defineProperty,yt=Object.defineProperties,$t=Object.getOwnPropertyDescriptor,xt=Object.getOwnPropertyDescriptors,wt=Object.getOwnPropertyNames,E=Object.getOwnPropertySymbols;var _=Object.prototype.hasOwnProperty,Y=Object.prototype.propertyIsEnumerable;var X=(t,r,n)=>r in t?I(t,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[r]=n,b=(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},j=(t,r)=>yt(t,xt(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 ht=(t,r)=>{for(var n in r)I(t,n,{get:r[n],enumerable:!0})},bt=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of wt(r))!_.call(t,o)&&o!==n&&I(t,o,{get:()=>r[o],enumerable:!(e=$t(r,o))||e.enumerable});return t};var Ft=t=>bt(I({},"__esModule",{value:!0}),t);var Nt={};ht(Nt,{Generate:()=>C,configFileExists:()=>ot,configFilePath:()=>et,defaultConfigFile:()=>J,generateIndexFile:()=>V,generateInterface:()=>U,generateInterfaceFile:()=>W,generateProjectIndexFile:()=>q,generateTypesFile:()=>K,getConfigFile:()=>it,getProjectConfig:()=>A,jsTypeFromAbiType:()=>g,makePureTypes:()=>M,run:()=>ut.run});module.exports=Ft(Nt);var ut=require("@oclif/command");var y=require("path"),N=require("fs/promises"),nt=require("fs");var B=require("@ltd/j-toml"),L=require("path"),R=require("fs/promises"),k=require("micro-stacks/wallet-sdk"),z=require("toposort"),G=require("micro-stacks/crypto");async function At(t){let r=(0,L.resolve)(t,"settings","Devnet.toml"),n=await(0,R.readFile)(r,{encoding:"utf-8"});return(0,B.parse)(n,1,`
2
- `,!0,{longer:!0})}async function Pt(t){let r=(0,L.resolve)(t,"Clarinet.toml"),n=await(0,R.readFile)(r,{encoding:"utf-8"});return(0,B.parse)(n,1,`
3
- `,!0)}async function tt(t,r){let n=await Pt(t),e=r.deployer.address;return Tt(n.contracts).map(c=>({file:n.contracts[c].path.replace(/^contracts\//,""),address:e,name:c}))}function Tt(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 At(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,G.StacksNetworkVersion.testnetP2PKH);return[o,j(b({},i),{address:a})]}));return Object.fromEntries(n)}var J={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 b(b({},J),o)}return J}async function A(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 j(b({},r),{contracts:o,contractsDir:i,accounts:e,clarinet:r.clarinet||"."})}var l=require("micro-stacks/transactions"),D=require("@clarigen/core"),st=require("reserved-words"),g=(t,r=!1)=>{if((0,l.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,l.isClarityAbiBuffer)(t))return"Uint8Array";if((0,l.isClarityAbiResponse)(t)){let n=g(t.response.ok),e=g(t.response.error);return`Response<${n}, ${e}>`}else{if((0,l.isClarityAbiOptional)(t))return`${g(t.optional)} | null`;if((0,l.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,l.isClarityAbiList)(t))return`${g(t.list.type)}[]`;if((0,l.isClarityAbiStringAscii)(t))return"string";if((0,l.isClarityAbiStringUtf8)(t))return"string";if(t==="trait_reference")return"string";throw new Error(`Unexpected Clarity ABI type: ${JSON.stringify(t)}`)}}}};function Et(t){let r=(0,D.toCamelCase)(t);return`${(0,st.check)(r,6)?"_":""}${r}`}var It={public:"Public",read_only:"ReadOnly",private:"Private"};function M(t){let r="";return t.functions.forEach((n,e)=>{let o=`${(0,D.toCamelCase)(n.name)}: `;if(o+=`(${n.args.map(s=>`${Et(s.name)}: ${g(s.type,!0)}`).join(", ")}) => `,o+=`ContractCalls.${It[n.access]}<`,n.access==="public"){let{type:s}=n.outputs;if(!(0,l.isClarityAbiResponse)(s))throw new Error("Expected response type for public function");let a=g(s.response.ok),f=g(s.response.error);o+=`${a}, ${f}>;`}else o+=`${g(n.outputs.type)}>;`;r+=`${e===0?"":`
7
- `} ${o}`}),t.maps.forEach(n=>{let e=`${(0,D.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"),v=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,f]=s.split(`
12
+ `)){let[f,l]=s.split(`
13
13
  Near:
14
- `),u="",m=/start_line: (\d+),/.exec(f);throw m&&(u=m[1]),new Error(`Error on ${r}:
15
- ${a}
16
- ${u?`Near line ${u}`:""}
17
- Raw trace:
14
+ `),y="",C=/start_line: (\d+),/.exec(l);throw C&&(y=C[1]),new Error(`Error on ${e}:
18
15
  ${f}
19
- `)}throw new Error(`Error on ${r}:
16
+ ${y?`Near line ${y}`:""}
17
+ Raw trace:
18
+ ${l}
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,42 +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 { Response, 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 f=t.accounts[a];return`"${a}": {
56
- mnemonic: "${f.mnemonic}",
57
- balance: ${f.balance.toString()}n,
58
- address: "${f.address}",
55
+ ${Object.keys(t.accounts).map(f=>{let l=t.accounts[f];return`"${f}": {
56
+ mnemonic: "${l.mnemonic}",
57
+ balance: ${l.balance.toString()}n,
58
+ address: "${l.address}",
59
59
  },`}).join(`
60
60
  `)}
61
- };`),t.contracts.forEach(s=>{let a=s.name,f=(0,$.toCamelCase)(a),u=`${f}Info`,h=`${(0,$.toCamelCase)(a,!0)}Contract`,m=(0,v.dirname)(s.file),Q=`'./${(0,v.join)(m||".",a)}'`,mt=`import { ${u} } from ${Q};`;r.push(mt);let Ct=`export type { ${h} } from ${Q};`;n.push(Ct);let dt=`${f}: ${u},`;e.push(dt)});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"),w=require("fs/promises");var S=require("@clarigen/claridocs"),x=require("fs/promises"),F=require("path");async function at({contractFile:t,contractName:r,docsPath:n,abi:e,dirName:o}){let i=await(0,x.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`),f=(0,S.generateMarkdown)({contract:c,contractFile:(0,F.relative)(s,t),contractName:r,abi:e});await(0,x.mkdir)(s,{recursive:!0}),await(0,x.writeFile)(a,f)}async function ft(t){if(!t.docs)return;let n=`# Contracts
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
73
 
74
74
  ${t.contracts.map(o=>{let i=o.file.replace(".clar",".md");return`- [\`${o.name}\`](${i})`}).join(`
75
75
  `)}
76
- `,e=(0,F.resolve)(process.cwd(),t.docs,"README.md");await(0,x.writeFile)(e,n)}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}),f=K(a,i),u=V({contractFile:(0,p.relative)(process.cwd(),s),contractAddress:e,contractName:i}),h=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,w.mkdir)(m,{recursive:!0}),await(0,w.writeFile)((0,p.resolve)(m,"abi.ts"),h),await(0,w.writeFile)((0,p.resolve)(m,"index.ts"),u),await(0,w.writeFile)((0,p.resolve)(m,"types.ts"),f)},O=async t=>{let r=await A(t),{contractsDir:n,outputDir:e,contracts:o}=r,i=(0,p.resolve)(t,e),c=await(0,lt.createClarityBin)();for(let f of o){let u=(0,p.resolve)(t,n,f.file),h=(0,p.dirname)(f.file);await jt({contractFile:u,outputFolder:i,provider:c,contractAddress:f.address,dirName:h,contractName:f.name,docsPath:r.docs})}let s=q(r);await ft(r);let a=(0,p.resolve)(i,"index.ts");await(0,w.writeFile)(a,s)};var pt=require("chokidar"),gt=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 A(n),i=(0,pt.watch)([o],{cwd:n});try{await O(n),e.succeed("Finished generating files. Watching for changes.")}catch(c){e.fail(`Error generating files.
77
- ${c.message}`)}i.on("change",async c=>{let s=(0,gt.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 f=a.message;e.fail(`Error after saving ${(0,T.red)(s)}.
78
- ${f}`)}}),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});
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 rt=Object.defineProperty,nt=Object.defineProperties;var et=Object.getOwnPropertyDescriptors;var w=Object.getOwnPropertySymbols;var k=Object.prototype.hasOwnProperty,N=Object.prototype.propertyIsEnumerable;var j=(t,n,r)=>n in t?rt(t,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[n]=r,$=(t,n)=>{for(var r in n||(n={}))k.call(n,r)&&j(t,r,n[r]);if(w)for(var r of w(n))N.call(n,r)&&j(t,r,n[r]);return t},h=(t,n)=>nt(t,et(n));var ot=(t=>typeof require!="undefined"?require:typeof Proxy!="undefined"?new Proxy(t,{get:(n,r)=>(typeof require!="undefined"?require:n)[r]}):t)(function(t){if(typeof require!="undefined")return require.apply(this,arguments);throw new Error('Dynamic require of "'+t+'" is not supported')});var D=(t,n)=>{var r={};for(var e in t)k.call(t,e)&&n.indexOf(e)<0&&(r[e]=t[e]);if(t!=null&&w)for(var e of w(t))n.indexOf(e)<0&&N.call(t,e)&&(r[e]=t[e]);return r};import{run as Vr}from"@oclif/command";import{resolve as R,join as gt,relative as ut}from"path";import{readFile as mt,access as Ct}from"fs/promises";import{constants as dt}from"fs";import{parse as v}from"@ltd/j-toml";import{resolve as S}from"path";import{readFile as O}from"fs/promises";import{generateWallet as it,getStxAddressFromAccount as st}from"micro-stacks/wallet-sdk";import{array as ct}from"toposort";import{StacksNetworkVersion as at}from"micro-stacks/crypto";async function ft(t){let n=S(t,"settings","Devnet.toml"),r=await O(n,{encoding:"utf-8"});return v(r,1,`
2
- `,!0,{longer:!0})}async function lt(t){let n=S(t,"Clarinet.toml"),r=await O(n,{encoding:"utf-8"});return v(r,1,`
3
- `,!0)}async function _(t,n){let r=await lt(t),e=n.deployer.address;return pt(r.contracts).map(c=>({file:r.contracts[c].path.replace(/^contracts\//,""),address:e,name:c}))}function pt(t){let n=[],r=[];return Object.entries(t).forEach(([o,i])=>{r.push(o),i.depends_on.forEach(c=>n.push([o,c]))}),ct(r,n).reverse()}async function B(t){let n=await ft(t),r=await Promise.all(Object.entries(n.accounts).map(async([o,i])=>{let c=await it(i.mnemonic,"password"),[s]=c.accounts,a=st(s,at.testnetP2PKH);return[o,h($({},i),{address:a})]}));return Object.fromEntries(r)}var L={outputDir:"src/clarigen",clarinet:"."};function yt(t){return R(t,"clarigen.config.json")}async function $t(t){try{return await Ct(t,dt.R_OK),!0}catch{return!1}}async function xt(t){let n=yt(t);if(await $t(n)){let e=await mt(n,{encoding:"utf-8"}),o=JSON.parse(e);return $($({},L),o)}return L}async function b(t){let n=await xt(t),r=R(t,n.clarinet||"."),e=await B(r),o=await _(r,e),i=ut(process.cwd(),gt(n.clarinet,"contracts"));return h($({},n),{contracts:o,contractsDir:i,accounts:e,clarinet:n.clarinet||"."})}import{isClarityAbiBuffer as wt,isClarityAbiList as ht,isClarityAbiOptional as bt,isClarityAbiPrimitive as Ft,isClarityAbiResponse as J,isClarityAbiStringAscii as At,isClarityAbiStringUtf8 as Pt,isClarityAbiTuple as Tt}from"micro-stacks/transactions";import{toCamelCase as P}from"@clarigen/core";import{check as Et}from"reserved-words";var l=(t,n=!1)=>{if(Ft(t)){if(t==="uint128")return n?"number | bigint":"bigint";if(t==="int128")return n?"number | bigint":"bigint";if(t==="bool")return"boolean";if(t==="principal")return"string";if(t==="none")return"null";if(t==="trait_reference")return"string";throw new Error(`Unexpected Clarity ABI type primitive: ${JSON.stringify(t)}`)}else{if(wt(t))return"Uint8Array";if(J(t)){let r=l(t.response.ok),e=l(t.response.error);return`Response<${r}, ${e}>`}else{if(bt(t))return`${l(t.optional)} | null`;if(Tt(t)){let r=[];return t.tuple.forEach(({name:e,type:o})=>{let i=l(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(ht(t))return`${l(t.list.type)}[]`;if(At(t))return"string";if(Pt(t))return"string";if(t==="trait_reference")return"string";throw new Error(`Unexpected Clarity ABI type: ${JSON.stringify(t)}`)}}}};function It(t){let n=P(t);return`${Et(n,6)?"_":""}${n}`}var jt={public:"Public",read_only:"ReadOnly",private:"Private"};function M(t){let n="";return t.functions.forEach((r,e)=>{let o=`${P(r.name)}: `;if(o+=`(${r.args.map(s=>`${It(s.name)}: ${l(s.type,!0)}`).join(", ")}) => `,o+=`ContractCalls.${jt[r.access]}<`,r.access==="public"){let{type:s}=r.outputs;if(!J(s))throw new Error("Expected response type for public function");let a=l(s.response.ok),f=l(s.response.error);o+=`${a}, ${f}>;`}else o+=`${l(r.outputs.type)}>;`;n+=`${e===0?"":`
7
- `} ${o}`}),t.maps.forEach(r=>{let e=`${P(r.name)}: `,o=l(r.key,!0),i=`key: ${o}`,c=l(r.value);e+=`(${i}) => ContractCalls.Map<${o}, ${c}>;`,n+=`
8
- ${e}`}),n}import{hasStdErr as kt}from"@clarigen/native-bin";import{toCamelCase as x}from"@clarigen/core";import{dirname as Nt,join as Dt}from"path";var U=async({provider:t,contractFile:n,contractAddress:r,contractName:e})=>{let o=await t.runCommand(["launch",`${r}.${e}`,n,t.dbFilePath,"--output_analysis","--costs","--assets"]);if(kt(o.stderr))throw new Error(`Error on ${n}:
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,f]=s.split(`
12
+ `)){let[p,l]=s.split(`
13
13
  Near:
14
- `),p="",g=/start_line: (\d+),/.exec(f);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
- ${f}
19
- `)}throw new Error(`Error on ${n}:
18
+ ${l}
19
+ `)}throw new Error(`Error on ${e}:
20
20
  ${JSON.stringify(i.error,null,2)}
21
- `)}return i.analysis},W=({contractName:t,abi:n})=>{let r=x(t,!0),s=n,{clarity_version:e}=s,o=D(s,["clarity_version"]),i=JSON.stringify(o,null,2);return`import { ClarityAbi } from '@clarigen/core';
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
- `},V=({contractFile:t,contractAddress:n,contractName:r})=>{let e=x(r,!0),o=x(r),i=`${e}Contract`,c=`${e}Interface`;return`import { pureProxy, Contract } from '@clarigen/core';
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,42 +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
- `},K=(t,n)=>{let r=x(n,!0),e=M(t);return`import { Response, 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
- `},q=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 f=t.accounts[a];return`"${a}": {
56
- mnemonic: "${f.mnemonic}",
57
- balance: ${f.balance.toString()}n,
58
- address: "${f.address}",
55
+ ${Object.keys(t.accounts).map(p=>{let l=t.accounts[p];return`"${p}": {
56
+ mnemonic: "${l.mnemonic}",
57
+ balance: ${l.balance.toString()}n,
58
+ address: "${l.address}",
59
59
  },`}).join(`
60
60
  `)}
61
- };`),t.contracts.forEach(s=>{let a=s.name,f=x(a),p=`${f}Info`,y=`${x(a,!0)}Contract`,g=Nt(s.file),I=`'./${Dt(g||".",a)}'`,z=`import { ${p} } from ${I};`;n.push(z);let G=`export type { ${y} } from ${I};`;r.push(G);let tt=`${f}: ${p},`;e.push(tt)});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 Wt,flags as Y}from"@oclif/command";import{createClarityBin as Lt}from"@clarigen/native-bin";import{resolve as u,relative as Rt,dirname as Jt}from"path";import{mkdir as Mt,writeFile as F}from"fs/promises";import{createContractDocInfo as vt,generateMarkdown as St}from"@clarigen/claridocs";import{mkdir as Ot,readFile as _t,writeFile as H}from"fs/promises";import{relative as Bt,resolve as T}from"path";async function Q({contractFile:t,contractName:n,docsPath:r,abi:e,dirName:o}){let i=await _t(t,{encoding:"utf-8"}),c=vt({contractSrc:i,abi:e}),s=T(process.cwd(),r,o||"."),a=T(s,`${n}.md`),f=St({contract:c,contractFile:Bt(s,t),contractName:n,abi:e});await Ot(s,{recursive:!0}),await H(a,f)}async function X(t){if(!t.docs)return;let r=`# Contracts
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
73
 
74
74
  ${t.contracts.map(o=>{let i=o.file.replace(".clar",".md");return`- [\`${o.name}\`](${i})`}).join(`
75
75
  `)}
76
- `,e=T(process.cwd(),t.docs,"README.md");await H(e,r)}var Ut=async({contractFile:t,outputFolder:n,provider:r,contractAddress:e,dirName:o,contractName:i,docsPath:c})=>{let s=u(process.cwd(),t),a=await U({contractFile:s,provider:r,contractAddress:e,contractName:i}),f=K(a,i),p=V({contractFile:Rt(process.cwd(),s),contractAddress:e,contractName:i}),y=W({contractName:i,abi:a});typeof c<"u"&&await Q({contractFile:s,contractName:i,abi:a,docsPath:c,dirName:o});let g=u(n,o||".",i);await Mt(g,{recursive:!0}),await F(u(g,"abi.ts"),y),await F(u(g,"index.ts"),p),await F(u(g,"types.ts"),f)},A=async t=>{let n=await b(t),{contractsDir:r,outputDir:e,contracts:o}=n,i=u(t,e),c=await Lt();for(let f of o){let p=u(t,r,f.file),y=Jt(f.file);await Ut({contractFile:p,outputFolder:i,provider:c,contractAddress:f.address,dirName:y,contractName:f.name,docsPath:n.docs})}let s=q(n);await X(n);let a=u(i,"index.ts");await F(a,s)};import{watch as Vt}from"chokidar";import{basename as Kt}from"path";import{red as qt,green as Z}from"chalk";var Ht=ot("ora"),E=class extends Wt{async run(){let{flags:n}=this.parse(E),r=process.cwd();if(n.watch){let e=Ht("Generating files").start(),{contractsDir:o}=await b(r),i=Vt([o],{cwd:r});try{await A(r),e.succeed("Finished generating files. Watching for changes.")}catch(c){e.fail(`Error generating files.
77
- ${c.message}`)}i.on("change",async c=>{let s=Kt(c);e.clear(),e.start(`Change detected for ${Z(s)}, generating.`);try{await A(r),e.succeed(`Finished generating files for ${Z(s)}. Watching for changes.`)}catch(a){let f=a.message;e.fail(`Error after saving ${qt(s)}.
78
- ${f}`)}}),process.on("SIGINT",async()=>{await i.close(),process.exit()})}else await A(r)}},d=E;d.description="Generate project files",d.strict=!0,d.hidden=!1,d.flags={help:Y.help({char:"h"}),watch:Y.boolean({char:"w",description:"Watch for changes to your contracts"})},d.args=[];export{d as Generate,$t as configFileExists,yt as configFilePath,L as defaultConfigFile,V as generateIndexFile,U as generateInterface,W as generateInterfaceFile,q as generateProjectIndexFile,K as generateTypesFile,xt as getConfigFile,b as getProjectConfig,l as jsTypeFromAbiType,M as makePureTypes,Vr as run};
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.17",
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.17",
53
- "@clarigen/core": "1.0.0-next.17",
54
- "@clarigen/native-bin": "1.0.0-next.17",
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": "6f61daa93601c4f1517dcd83b4e027a688f2fb6c"
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' });
@@ -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}`;
@@ -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
16
  import { generateDocsIndex, generateMarkdownDoc } from './docs';
17
+ import { ClarityAbi, Contract } from '@clarigen/core';
18
+ import { generateContractMeta, generateSingleFile } from './generate/single';
19
+ import { writeFile } from './writer';
20
+ import { getVariables, TypedAbiVariable } from './generate/vars';
21
+ import { ClarityAbiVariable } from 'micro-stacks/clarity';
22
+
23
+ export interface ContractMeta {
24
+ abi: ClarityAbi;
25
+ contractFile: string;
26
+ dirName: string;
27
+ contractName: string;
28
+ contractAddress: string;
29
+ variables: TypedAbiVariable<unknown>[];
30
+ }
16
31
 
17
32
  export const generateFilesForContract = async ({
18
33
  contractFile: _contractFile,
@@ -30,15 +45,21 @@ export const generateFilesForContract = async ({
30
45
  dirName?: string;
31
46
  contractName: string;
32
47
  docsPath?: string;
33
- }) => {
48
+ }): Promise<ContractMeta> => {
34
49
  const contractFile = resolve(process.cwd(), _contractFile);
50
+ const contractIdentifier = `${contractAddress}.${contractName}`;
35
51
 
36
- const abi = await generateInterface({
37
- contractFile,
52
+ const abi = await deployContract({
53
+ contractIdentifier,
54
+ contractFilePath: contractFile,
38
55
  provider,
39
- contractAddress,
40
- contractName,
41
56
  });
57
+ const variables = await getVariables({
58
+ abi,
59
+ contractIdentifier,
60
+ provider,
61
+ });
62
+
42
63
  const typesFile = generateTypesFile(abi, contractName);
43
64
  const indexFile = generateIndexFile({
44
65
  contractFile: relative(process.cwd(), contractFile),
@@ -63,6 +84,15 @@ export const generateFilesForContract = async ({
63
84
  await writeFile(resolve(outputPath, 'abi.ts'), abiFile);
64
85
  await writeFile(resolve(outputPath, 'index.ts'), indexFile);
65
86
  await writeFile(resolve(outputPath, 'types.ts'), typesFile);
87
+
88
+ return {
89
+ abi,
90
+ contractFile,
91
+ contractName,
92
+ dirName,
93
+ contractAddress,
94
+ variables,
95
+ };
66
96
  };
67
97
 
68
98
  export const generateProject = async (projectPath: string) => {
@@ -70,11 +100,12 @@ export const generateProject = async (projectPath: string) => {
70
100
  const { contractsDir, outputDir, contracts } = configFile;
71
101
  const outputFolder = resolve(projectPath, outputDir);
72
102
  const provider = await createClarityBin();
103
+ const metas: ContractMeta[] = [];
73
104
  // this needs to be serial
74
105
  for (const contract of contracts) {
75
106
  const contractFile = resolve(projectPath, contractsDir, contract.file);
76
107
  const dirName = dirname(contract.file);
77
- await generateFilesForContract({
108
+ const meta = await generateFilesForContract({
78
109
  contractFile,
79
110
  outputFolder: outputFolder,
80
111
  provider,
@@ -83,6 +114,7 @@ export const generateProject = async (projectPath: string) => {
83
114
  contractName: contract.name,
84
115
  docsPath: configFile.docs,
85
116
  });
117
+ metas.push(meta);
86
118
  }
87
119
 
88
120
  const indexFile = generateProjectIndexFile(configFile);
@@ -90,4 +122,8 @@ export const generateProject = async (projectPath: string) => {
90
122
 
91
123
  const indexPath = resolve(outputFolder, 'index.ts');
92
124
  await writeFile(indexPath, indexFile);
125
+
126
+ const singleFile = await generateSingleFile(configFile, metas);
127
+ const singlePath = resolve(outputFolder, 'single.ts');
128
+ await writeFile(singlePath, singleFile);
93
129
  };
package/src/writer.ts ADDED
@@ -0,0 +1,39 @@
1
+ // Utilities for writing and formatting files
2
+ import { writeFile as _writeFile } from 'fs/promises';
3
+ import { basename } from 'path';
4
+ import { resolveConfig, format, Options } from 'prettier';
5
+
6
+ const defaultPrettierConfig: Options = {
7
+ printWidth: 80,
8
+ semi: true,
9
+ singleQuote: true,
10
+ trailingComma: 'es5',
11
+ };
12
+
13
+ export async function resolvePrettierConfig(): Promise<Options> {
14
+ try {
15
+ const local = await resolveConfig(process.cwd());
16
+ if (local) return local;
17
+ } catch (error) {}
18
+ return defaultPrettierConfig;
19
+ }
20
+
21
+ export async function formatFile(contents: string, path: string) {
22
+ try {
23
+ const fileName = basename(path);
24
+ const config = await resolvePrettierConfig();
25
+ const formatted = format(contents, {
26
+ ...config,
27
+ filepath: fileName,
28
+ });
29
+ return formatted;
30
+ } catch (error) {
31
+ // handle formatting error
32
+ }
33
+ return contents;
34
+ }
35
+
36
+ export async function writeFile(path: string, contents: string) {
37
+ const formatted = await formatFile(contents, path);
38
+ await _writeFile(path, formatted);
39
+ }