@clarigen/cli 0.3.3 → 1.0.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/index.d.ts +16 -0
- package/dist/commands/index.js +72 -63
- package/dist/commands/index.mjs +74 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +73 -18
- package/dist/index.mjs +74 -0
- package/package.json +18 -13
- package/src/clarinet-config.ts +39 -16
- package/src/commands/index.ts +2 -2
- package/src/config.ts +50 -32
- package/src/generate/declaration.ts +33 -57
- package/src/generate/files.ts +39 -36
- package/src/utils.ts +13 -14
- package/dist/clarinet-config.js +0 -57
- package/dist/commands/contract.js +0 -33
- package/dist/config.js +0 -31
- package/dist/generate/declaration.js +0 -157
- package/dist/generate/files.js +0 -141
- package/dist/start.js +0 -9
- package/dist/utils.js +0 -56
- package/src/commands/contract.ts +0 -35
package/src/clarinet-config.ts
CHANGED
|
@@ -2,7 +2,12 @@ import { parse } from '@ltd/j-toml';
|
|
|
2
2
|
import { resolve } from 'path';
|
|
3
3
|
import { readFile } from 'fs/promises';
|
|
4
4
|
import { ConfigContract } from './config';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
generateWallet,
|
|
7
|
+
getStxAddressFromAccount,
|
|
8
|
+
} from 'micro-stacks/wallet-sdk';
|
|
9
|
+
import { array as toposort } from 'toposort';
|
|
10
|
+
import { StacksNetworkVersion } from 'micro-stacks/crypto';
|
|
6
11
|
|
|
7
12
|
interface ClarinetConfigAccount {
|
|
8
13
|
mnemonic: string;
|
|
@@ -30,13 +35,17 @@ export async function getClarinetDevConfig(
|
|
|
30
35
|
return config;
|
|
31
36
|
}
|
|
32
37
|
|
|
33
|
-
interface
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
export interface ClarinetContract {
|
|
39
|
+
path: string;
|
|
40
|
+
depends_on: string[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface ClarinetContracts {
|
|
44
|
+
[name: string]: ClarinetContract;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface ClarinetConfig {
|
|
48
|
+
contracts: ClarinetContracts;
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
export async function getClarinetConfig(folder: string) {
|
|
@@ -57,18 +66,32 @@ export async function getContractsFromClarinet(
|
|
|
57
66
|
): Promise<ConfigContract[]> {
|
|
58
67
|
const clarinetConfig = await getClarinetConfig(folder);
|
|
59
68
|
const deployerAddress = accounts.deployer.address;
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
69
|
+
const sortedContracts = sortClarinetContracts(clarinetConfig.contracts);
|
|
70
|
+
const contracts: ConfigContract[] = sortedContracts.map((contractName) => {
|
|
71
|
+
const info = clarinetConfig.contracts[contractName];
|
|
63
72
|
const file = info.path.replace(/^contracts\//, '');
|
|
64
73
|
return {
|
|
65
74
|
file,
|
|
66
75
|
address: deployerAddress,
|
|
76
|
+
name: contractName,
|
|
67
77
|
};
|
|
68
78
|
});
|
|
69
79
|
return contracts;
|
|
70
80
|
}
|
|
71
81
|
|
|
82
|
+
export function sortClarinetContracts(contractsConfig: ClarinetContracts) {
|
|
83
|
+
const edges: [string, string][] = [];
|
|
84
|
+
const nodes: string[] = [];
|
|
85
|
+
Object.entries(contractsConfig).forEach(([contractName, info]) => {
|
|
86
|
+
nodes.push(contractName);
|
|
87
|
+
info.depends_on.forEach((dependency) =>
|
|
88
|
+
edges.push([contractName, dependency])
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
const sorted = toposort(nodes, edges).reverse();
|
|
92
|
+
return sorted;
|
|
93
|
+
}
|
|
94
|
+
|
|
72
95
|
export interface ClarinetAccount extends ClarinetConfigAccount {
|
|
73
96
|
address: string;
|
|
74
97
|
}
|
|
@@ -84,12 +107,12 @@ export async function getClarinetAccounts(
|
|
|
84
107
|
const devConfig = await getClarinetDevConfig(folder);
|
|
85
108
|
const accountEntries = await Promise.all(
|
|
86
109
|
Object.entries(devConfig.accounts).map(async ([key, info]) => {
|
|
87
|
-
const wallet = await generateWallet(
|
|
88
|
-
secretKey: info.mnemonic,
|
|
89
|
-
password: 'password',
|
|
90
|
-
});
|
|
110
|
+
const wallet = await generateWallet(info.mnemonic, 'password');
|
|
91
111
|
const [account] = wallet.accounts;
|
|
92
|
-
const address =
|
|
112
|
+
const address = getStxAddressFromAccount(
|
|
113
|
+
account,
|
|
114
|
+
StacksNetworkVersion.testnetP2PKH
|
|
115
|
+
);
|
|
93
116
|
return [
|
|
94
117
|
key,
|
|
95
118
|
{
|
package/src/commands/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command, flags } from '@oclif/command';
|
|
2
2
|
import { generateProject } from '../utils';
|
|
3
|
-
import {
|
|
3
|
+
import { getProjectConfig } from '../config';
|
|
4
4
|
import { watch } from 'chokidar';
|
|
5
5
|
import { basename } from 'path';
|
|
6
6
|
import { red, green } from 'chalk';
|
|
@@ -28,7 +28,7 @@ export class Generate extends Command {
|
|
|
28
28
|
|
|
29
29
|
if (flags.watch) {
|
|
30
30
|
const spinner = ora('Generating files').start();
|
|
31
|
-
const { contractsDir } = await
|
|
31
|
+
const { contractsDir } = await getProjectConfig(cwd);
|
|
32
32
|
const watcher = watch([contractsDir], {
|
|
33
33
|
cwd,
|
|
34
34
|
});
|
package/src/config.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { resolve, join, relative } from 'path';
|
|
2
|
-
import { readFile } from 'fs/promises';
|
|
2
|
+
import { readFile, access } from 'fs/promises';
|
|
3
|
+
import { constants } from 'fs';
|
|
3
4
|
import {
|
|
4
5
|
ClarinetAccounts,
|
|
5
6
|
getClarinetAccounts,
|
|
@@ -9,52 +10,69 @@ import {
|
|
|
9
10
|
export interface ConfigContract {
|
|
10
11
|
address: string;
|
|
11
12
|
file: string;
|
|
13
|
+
name: string;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
export interface
|
|
16
|
+
export interface ConfigFileContents {
|
|
15
17
|
outputDir: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface ConfigFileWithClarinet extends ConfigFileBase {
|
|
19
18
|
clarinet: string;
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
export interface
|
|
21
|
+
export interface ConfigFile extends ConfigFileContents {
|
|
23
22
|
contractsDir: string;
|
|
24
23
|
contracts: ConfigContract[];
|
|
24
|
+
accounts: ClarinetAccounts;
|
|
25
|
+
clarinet: string;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
export
|
|
28
|
+
export const defaultConfigFile: ConfigFileContents = {
|
|
29
|
+
outputDir: 'src/clarigen',
|
|
30
|
+
clarinet: '.',
|
|
31
|
+
};
|
|
28
32
|
|
|
29
|
-
export
|
|
30
|
-
|
|
31
|
-
accounts: ClarinetAccounts;
|
|
33
|
+
export function configFilePath(rootPath: string) {
|
|
34
|
+
return resolve(rootPath, 'clarigen.config.json');
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
export
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
export async function configFileExists(configPath: string): Promise<boolean> {
|
|
38
|
+
try {
|
|
39
|
+
await access(configPath, constants.R_OK);
|
|
40
|
+
return true;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export async function getConfigFile(
|
|
47
|
+
rootPath: string
|
|
48
|
+
): Promise<ConfigFileContents> {
|
|
49
|
+
const fullPath = configFilePath(rootPath);
|
|
50
|
+
const exists = await configFileExists(fullPath);
|
|
51
|
+
if (exists) {
|
|
52
|
+
const configContents = await readFile(fullPath, { encoding: 'utf-8' });
|
|
53
|
+
const configFile: ConfigFileContents = JSON.parse(configContents);
|
|
49
54
|
return {
|
|
55
|
+
...defaultConfigFile,
|
|
50
56
|
...configFile,
|
|
51
|
-
contracts,
|
|
52
|
-
contractsDir,
|
|
53
|
-
accounts,
|
|
54
57
|
};
|
|
55
58
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
return defaultConfigFile;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export async function getProjectConfig(rootPath: string): Promise<ConfigFile> {
|
|
63
|
+
const configFile = await getConfigFile(rootPath);
|
|
64
|
+
const clarinetPath = resolve(rootPath, configFile.clarinet || '.');
|
|
65
|
+
const accounts = await getClarinetAccounts(clarinetPath);
|
|
66
|
+
const contracts = await getContractsFromClarinet(clarinetPath, accounts);
|
|
67
|
+
const contractsDir = relative(
|
|
68
|
+
process.cwd(),
|
|
69
|
+
join(configFile.clarinet, 'contracts')
|
|
70
|
+
);
|
|
71
|
+
return {
|
|
72
|
+
...configFile,
|
|
73
|
+
contracts,
|
|
74
|
+
contractsDir,
|
|
75
|
+
accounts,
|
|
76
|
+
clarinet: configFile.clarinet || '.',
|
|
77
|
+
};
|
|
60
78
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ClarityAbiType,
|
|
3
2
|
isClarityAbiBuffer,
|
|
4
3
|
isClarityAbiList,
|
|
5
4
|
isClarityAbiOptional,
|
|
@@ -8,44 +7,10 @@ import {
|
|
|
8
7
|
isClarityAbiStringAscii,
|
|
9
8
|
isClarityAbiStringUtf8,
|
|
10
9
|
isClarityAbiTuple,
|
|
11
|
-
} from '
|
|
10
|
+
} from 'micro-stacks/transactions';
|
|
11
|
+
import { ClarityAbiFunction, ClarityAbiType } from 'micro-stacks/clarity';
|
|
12
12
|
import { toCamelCase, ClarityAbi } from '@clarigen/core';
|
|
13
|
-
|
|
14
|
-
export const cvFromType = (val: ClarityAbiType) => {
|
|
15
|
-
if (isClarityAbiPrimitive(val)) {
|
|
16
|
-
if (val === 'uint128') {
|
|
17
|
-
return 'ClarityTypes.UIntCV';
|
|
18
|
-
} else if (val === 'int128') {
|
|
19
|
-
return 'ClarityTypes.IntCV';
|
|
20
|
-
} else if (val === 'bool') {
|
|
21
|
-
return 'ClarityTypes.BooleanCV';
|
|
22
|
-
} else if (val === 'principal') {
|
|
23
|
-
return 'ClarityTypes.PrincipalCV';
|
|
24
|
-
} else if (val === 'none') {
|
|
25
|
-
return 'ClarityTypes.NoneCV';
|
|
26
|
-
} else {
|
|
27
|
-
throw new Error(
|
|
28
|
-
`Unexpected Clarity ABI type primitive: ${JSON.stringify(val)}`
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
} else if (isClarityAbiBuffer(val)) {
|
|
32
|
-
return 'ClarityTypes.BufferCV';
|
|
33
|
-
} else if (isClarityAbiResponse(val)) {
|
|
34
|
-
return 'ClarityTypes.ResponseCV';
|
|
35
|
-
} else if (isClarityAbiOptional(val)) {
|
|
36
|
-
return 'ClarityTypes.OptionalCV';
|
|
37
|
-
} else if (isClarityAbiTuple(val)) {
|
|
38
|
-
return 'ClarityTypes.TupleCV';
|
|
39
|
-
} else if (isClarityAbiList(val)) {
|
|
40
|
-
return 'ClarityTypes.ListCV';
|
|
41
|
-
} else if (isClarityAbiStringAscii(val)) {
|
|
42
|
-
return 'ClarityTypes.StringAsciiCV';
|
|
43
|
-
} else if (isClarityAbiStringUtf8(val)) {
|
|
44
|
-
return 'ClarityTypes.StringUtf8CV';
|
|
45
|
-
} else {
|
|
46
|
-
throw new Error(`Unexpected Clarity ABI type: ${JSON.stringify(val)}`);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
13
|
+
import { check } from 'reserved-words';
|
|
49
14
|
|
|
50
15
|
export const jsTypeFromAbiType = (
|
|
51
16
|
val: ClarityAbiType,
|
|
@@ -72,7 +37,7 @@ export const jsTypeFromAbiType = (
|
|
|
72
37
|
);
|
|
73
38
|
}
|
|
74
39
|
} else if (isClarityAbiBuffer(val)) {
|
|
75
|
-
return '
|
|
40
|
+
return 'Uint8Array';
|
|
76
41
|
} else if (isClarityAbiResponse(val)) {
|
|
77
42
|
const ok: any = jsTypeFromAbiType(val.response.ok);
|
|
78
43
|
const err: any = jsTypeFromAbiType(val.response.error);
|
|
@@ -103,38 +68,49 @@ export const jsTypeFromAbiType = (
|
|
|
103
68
|
}
|
|
104
69
|
};
|
|
105
70
|
|
|
106
|
-
|
|
71
|
+
// Check if it's a reserved word, and then camelCase
|
|
72
|
+
function getArgName(name: string) {
|
|
73
|
+
const camel = toCamelCase(name);
|
|
74
|
+
const prefix = check(camel, 6) ? '_' : '';
|
|
75
|
+
return `${prefix}${camel}`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const accessToReturnType = {
|
|
79
|
+
public: 'Public',
|
|
80
|
+
read_only: 'ReadOnly',
|
|
81
|
+
private: 'Private',
|
|
82
|
+
} as const;
|
|
83
|
+
|
|
84
|
+
export function makePureTypes(abi: ClarityAbi) {
|
|
107
85
|
let typings = '';
|
|
108
86
|
abi.functions.forEach((func, index) => {
|
|
109
|
-
if (func.access === 'private') return;
|
|
110
87
|
let functionLine = `${toCamelCase(func.name)}: `;
|
|
111
88
|
const args = func.args.map((arg) => {
|
|
112
|
-
return `${
|
|
89
|
+
return `${getArgName(arg.name)}: ${jsTypeFromAbiType(arg.type, true)}`;
|
|
113
90
|
});
|
|
114
91
|
functionLine += `(${args.join(', ')}) => `;
|
|
92
|
+
const funcType = accessToReturnType[func.access];
|
|
93
|
+
functionLine += `ContractCalls.${funcType}<`;
|
|
115
94
|
if (func.access === 'public') {
|
|
116
95
|
const { type } = func.outputs;
|
|
117
96
|
if (!isClarityAbiResponse(type))
|
|
118
97
|
throw new Error('Expected response type for public function');
|
|
119
|
-
functionLine += 'Transaction';
|
|
120
98
|
const ok = jsTypeFromAbiType(type.response.ok);
|
|
121
99
|
const err = jsTypeFromAbiType(type.response.error);
|
|
122
|
-
functionLine +=
|
|
100
|
+
functionLine += `${ok}, ${err}>;`;
|
|
123
101
|
} else {
|
|
124
|
-
const
|
|
125
|
-
functionLine +=
|
|
126
|
-
// const { type } = func.outputs;
|
|
127
|
-
// if (isClarityAbiResponse(type)) {
|
|
128
|
-
// const ok = jsTypeFromAbiType(type.response.ok);
|
|
129
|
-
// const err = jsTypeFromAbiType(type.response.error);
|
|
130
|
-
// functionLine += `Promise<ClarityTypes.Response<${ok}, ${err}>>;`;
|
|
131
|
-
// } else {
|
|
132
|
-
// const jsType = jsTypeFromAbiType(func.outputs.type);
|
|
133
|
-
// functionLine += `Promise<${jsType}>;`;
|
|
134
|
-
// }
|
|
102
|
+
const returnType = jsTypeFromAbiType(func.outputs.type);
|
|
103
|
+
functionLine += `${returnType}>;`;
|
|
135
104
|
}
|
|
136
105
|
typings += `${index === 0 ? '' : '\n'} ${functionLine}`;
|
|
137
106
|
});
|
|
138
|
-
|
|
107
|
+
abi.maps.forEach((map) => {
|
|
108
|
+
let functionLine = `${toCamelCase(map.name)}: `;
|
|
109
|
+
const keyType = jsTypeFromAbiType(map.key, true);
|
|
110
|
+
const arg = `key: ${keyType}`;
|
|
111
|
+
const valType = jsTypeFromAbiType(map.value);
|
|
112
|
+
functionLine += `(${arg}) => ContractCalls.Map<${keyType}, ${valType}>;`;
|
|
113
|
+
typings += `\n ${functionLine}`;
|
|
114
|
+
});
|
|
139
115
|
return typings;
|
|
140
|
-
}
|
|
116
|
+
}
|
package/src/generate/files.ts
CHANGED
|
@@ -1,28 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
createClarityBin,
|
|
4
|
-
hasStdErr,
|
|
5
|
-
} from '@clarigen/native-bin';
|
|
6
|
-
import {
|
|
7
|
-
ClarityAbi,
|
|
8
|
-
toCamelCase,
|
|
9
|
-
getContractNameFromPath,
|
|
10
|
-
} from '@clarigen/core';
|
|
11
|
-
import { makeTypes } from './declaration';
|
|
1
|
+
import { NativeClarityBinProvider, hasStdErr } from '@clarigen/native-bin';
|
|
2
|
+
import { ClarityAbi, toCamelCase } from '@clarigen/core';
|
|
12
3
|
import { ConfigContract, ConfigFile } from '../config';
|
|
13
4
|
import { dirname, resolve, join } from 'path';
|
|
5
|
+
import { makePureTypes } from '..';
|
|
14
6
|
|
|
15
7
|
export const generateInterface = async ({
|
|
16
|
-
provider
|
|
8
|
+
provider,
|
|
17
9
|
contractFile,
|
|
18
|
-
contractAddress
|
|
10
|
+
contractAddress,
|
|
11
|
+
contractName,
|
|
19
12
|
}: {
|
|
20
13
|
contractFile: string;
|
|
21
|
-
provider
|
|
22
|
-
contractAddress
|
|
14
|
+
provider: NativeClarityBinProvider;
|
|
15
|
+
contractAddress: string;
|
|
16
|
+
contractName: string;
|
|
23
17
|
}): Promise<ClarityAbi> => {
|
|
24
|
-
const provider = _provider || (await createClarityBin());
|
|
25
|
-
const contractName = getContractNameFromPath(contractFile);
|
|
26
18
|
const receipt = await provider.runCommand([
|
|
27
19
|
'launch',
|
|
28
20
|
`${contractAddress}.${contractName}`,
|
|
@@ -62,15 +54,15 @@ export const generateInterface = async ({
|
|
|
62
54
|
};
|
|
63
55
|
|
|
64
56
|
export const generateInterfaceFile = ({
|
|
65
|
-
|
|
57
|
+
contractName,
|
|
66
58
|
abi,
|
|
67
59
|
}: {
|
|
68
|
-
|
|
60
|
+
contractName: string;
|
|
69
61
|
abi: ClarityAbi;
|
|
70
62
|
}) => {
|
|
71
|
-
const contractName = getContractNameFromPath(contractFile);
|
|
72
63
|
const variableName = toCamelCase(contractName, true);
|
|
73
|
-
const
|
|
64
|
+
const { clarity_version, ...rest } = abi;
|
|
65
|
+
const abiString = JSON.stringify(rest, null, 2);
|
|
74
66
|
|
|
75
67
|
const fileContents = `import { ClarityAbi } from '@clarigen/core';
|
|
76
68
|
|
|
@@ -83,30 +75,37 @@ export const ${variableName}Interface: ClarityAbi = ${abiString};
|
|
|
83
75
|
|
|
84
76
|
export const generateIndexFile = ({
|
|
85
77
|
contractFile,
|
|
86
|
-
|
|
78
|
+
contractAddress,
|
|
79
|
+
contractName,
|
|
87
80
|
}: {
|
|
88
81
|
contractFile: string;
|
|
89
|
-
|
|
82
|
+
contractAddress: string;
|
|
83
|
+
contractName: string;
|
|
90
84
|
}) => {
|
|
91
|
-
const contractName = getContractNameFromPath(contractFile);
|
|
92
85
|
const contractTitle = toCamelCase(contractName, true);
|
|
93
86
|
const varName = toCamelCase(contractName);
|
|
94
87
|
const contractType = `${contractTitle}Contract`;
|
|
88
|
+
const interfaceVar = `${contractTitle}Interface`;
|
|
95
89
|
|
|
96
|
-
const fileContents = `import {
|
|
90
|
+
const fileContents = `import { pureProxy, Contract } from '@clarigen/core';
|
|
97
91
|
import type { ${contractType} } from './types';
|
|
98
|
-
import { ${
|
|
92
|
+
import { ${interfaceVar} } from './abi';
|
|
99
93
|
export type { ${contractType} } from './types';
|
|
100
94
|
|
|
101
|
-
export
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
95
|
+
export function ${varName}Contract(contractAddress: string, contractName: string) {
|
|
96
|
+
return pureProxy<${contractType}>({
|
|
97
|
+
abi: ${interfaceVar},
|
|
98
|
+
contractAddress,
|
|
99
|
+
contractName,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
105
102
|
|
|
106
103
|
export const ${varName}Info: Contract<${contractType}> = {
|
|
107
104
|
contract: ${varName}Contract,
|
|
108
|
-
address: '${
|
|
105
|
+
address: '${contractAddress}',
|
|
109
106
|
contractFile: '${contractFile}',
|
|
107
|
+
name: '${contractName}',
|
|
108
|
+
abi: ${interfaceVar},
|
|
110
109
|
};
|
|
111
110
|
`;
|
|
112
111
|
|
|
@@ -115,8 +114,8 @@ export const ${varName}Info: Contract<${contractType}> = {
|
|
|
115
114
|
|
|
116
115
|
export const generateTypesFile = (abi: ClarityAbi, contractName: string) => {
|
|
117
116
|
const name = toCamelCase(contractName, true);
|
|
118
|
-
const typings =
|
|
119
|
-
const fileContents = `import { ClarityTypes,
|
|
117
|
+
const typings = makePureTypes(abi);
|
|
118
|
+
const fileContents = `import { ClarityTypes, ContractCalls } from '@clarigen/core';
|
|
120
119
|
|
|
121
120
|
// prettier-ignore
|
|
122
121
|
export interface ${name}Contract {
|
|
@@ -128,7 +127,9 @@ ${typings}
|
|
|
128
127
|
};
|
|
129
128
|
|
|
130
129
|
export const generateProjectIndexFile = (config: ConfigFile) => {
|
|
131
|
-
const imports: string[] = [
|
|
130
|
+
const imports: string[] = [
|
|
131
|
+
"import type { ContractInstances } from '@clarigen/core';",
|
|
132
|
+
];
|
|
132
133
|
const exports: string[] = [];
|
|
133
134
|
const contractMap: string[] = [];
|
|
134
135
|
|
|
@@ -150,7 +151,7 @@ export const accounts = {
|
|
|
150
151
|
}
|
|
151
152
|
|
|
152
153
|
config.contracts.forEach((contract) => {
|
|
153
|
-
const contractName =
|
|
154
|
+
const contractName = contract.name;
|
|
154
155
|
const contractVar = toCamelCase(contractName);
|
|
155
156
|
const contractInfo = `${contractVar}Info`;
|
|
156
157
|
const contractInterface = `${toCamelCase(contractName, true)}Contract`;
|
|
@@ -167,9 +168,11 @@ export const accounts = {
|
|
|
167
168
|
contractMap.push(map);
|
|
168
169
|
});
|
|
169
170
|
|
|
171
|
+
const contractsType = `\nexport type Contracts = ContractInstances<typeof contracts>;\n`;
|
|
172
|
+
|
|
170
173
|
const file = `${imports.join('\n')}
|
|
171
174
|
${exports.join('\n')}
|
|
172
|
-
|
|
175
|
+
${contractsType}
|
|
173
176
|
export const contracts = {
|
|
174
177
|
${contractMap.join('\n ')}
|
|
175
178
|
};${accounts}
|
package/src/utils.ts
CHANGED
|
@@ -5,14 +5,13 @@ import {
|
|
|
5
5
|
generateProjectIndexFile,
|
|
6
6
|
generateTypesFile,
|
|
7
7
|
} from './generate/files';
|
|
8
|
-
import { getContractNameFromPath } from '@clarigen/core';
|
|
9
8
|
import {
|
|
10
9
|
NativeClarityBinProvider,
|
|
11
10
|
createClarityBin,
|
|
12
11
|
} from '@clarigen/native-bin';
|
|
13
12
|
import { resolve, relative, dirname } from 'path';
|
|
14
13
|
import { mkdir, writeFile } from 'fs/promises';
|
|
15
|
-
import {
|
|
14
|
+
import { getProjectConfig } from './config';
|
|
16
15
|
|
|
17
16
|
export const generateFilesForContract = async ({
|
|
18
17
|
contractFile: _contractFile,
|
|
@@ -20,33 +19,32 @@ export const generateFilesForContract = async ({
|
|
|
20
19
|
provider,
|
|
21
20
|
contractAddress,
|
|
22
21
|
dirName,
|
|
22
|
+
contractName,
|
|
23
23
|
}: {
|
|
24
24
|
contractFile: string;
|
|
25
|
-
outputFolder
|
|
26
|
-
provider
|
|
27
|
-
contractAddress
|
|
25
|
+
outputFolder: string;
|
|
26
|
+
provider: NativeClarityBinProvider;
|
|
27
|
+
contractAddress: string;
|
|
28
28
|
dirName?: string;
|
|
29
|
+
contractName: string;
|
|
29
30
|
}) => {
|
|
30
31
|
const contractFile = resolve(process.cwd(), _contractFile);
|
|
31
|
-
const contractName = getContractNameFromPath(contractFile);
|
|
32
32
|
|
|
33
33
|
const abi = await generateInterface({
|
|
34
34
|
contractFile,
|
|
35
35
|
provider,
|
|
36
36
|
contractAddress,
|
|
37
|
+
contractName,
|
|
37
38
|
});
|
|
38
39
|
const typesFile = generateTypesFile(abi, contractName);
|
|
39
|
-
if (!contractAddress && process.env.NODE_ENV !== 'test') {
|
|
40
|
-
console.warn('Please provide an address with every contract.');
|
|
41
|
-
}
|
|
42
40
|
const indexFile = generateIndexFile({
|
|
43
41
|
contractFile: relative(process.cwd(), contractFile),
|
|
44
|
-
|
|
42
|
+
contractAddress: contractAddress,
|
|
43
|
+
contractName,
|
|
45
44
|
});
|
|
46
|
-
const abiFile = generateInterfaceFile({
|
|
45
|
+
const abiFile = generateInterfaceFile({ contractName, abi });
|
|
47
46
|
|
|
48
|
-
const
|
|
49
|
-
const outputPath = resolve(baseDir, dirName || '.', contractName);
|
|
47
|
+
const outputPath = resolve(outputFolder, dirName || '.', contractName);
|
|
50
48
|
await mkdir(outputPath, { recursive: true });
|
|
51
49
|
|
|
52
50
|
await writeFile(resolve(outputPath, 'abi.ts'), abiFile);
|
|
@@ -55,7 +53,7 @@ export const generateFilesForContract = async ({
|
|
|
55
53
|
};
|
|
56
54
|
|
|
57
55
|
export const generateProject = async (projectPath: string) => {
|
|
58
|
-
const configFile = await
|
|
56
|
+
const configFile = await getProjectConfig(projectPath);
|
|
59
57
|
const { contractsDir, outputDir, contracts } = configFile;
|
|
60
58
|
const outputFolder = resolve(projectPath, outputDir);
|
|
61
59
|
const provider = await createClarityBin();
|
|
@@ -69,6 +67,7 @@ export const generateProject = async (projectPath: string) => {
|
|
|
69
67
|
provider,
|
|
70
68
|
contractAddress: contract.address,
|
|
71
69
|
dirName,
|
|
70
|
+
contractName: contract.name,
|
|
72
71
|
});
|
|
73
72
|
}
|
|
74
73
|
|
package/dist/clarinet-config.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getClarinetAccounts = exports.getContractsFromClarinet = exports.getClarinetConfig = exports.getClarinetDevConfig = void 0;
|
|
4
|
-
const j_toml_1 = require("@ltd/j-toml");
|
|
5
|
-
const path_1 = require("path");
|
|
6
|
-
const promises_1 = require("fs/promises");
|
|
7
|
-
const wallet_sdk_1 = require("@stacks/wallet-sdk");
|
|
8
|
-
async function getClarinetDevConfig(folder) {
|
|
9
|
-
const baseConfigPath = path_1.resolve(folder, 'settings', 'Devnet.toml');
|
|
10
|
-
const configContents = await promises_1.readFile(baseConfigPath, { encoding: 'utf-8' });
|
|
11
|
-
const config = j_toml_1.parse(configContents, 1.0, '\n', true, {
|
|
12
|
-
longer: true,
|
|
13
|
-
});
|
|
14
|
-
return config;
|
|
15
|
-
}
|
|
16
|
-
exports.getClarinetDevConfig = getClarinetDevConfig;
|
|
17
|
-
async function getClarinetConfig(folder) {
|
|
18
|
-
const baseConfigPath = path_1.resolve(folder, 'Clarinet.toml');
|
|
19
|
-
const configContents = await promises_1.readFile(baseConfigPath, { encoding: 'utf-8' });
|
|
20
|
-
const config = j_toml_1.parse(configContents, 1.0, '\n', true);
|
|
21
|
-
return config;
|
|
22
|
-
}
|
|
23
|
-
exports.getClarinetConfig = getClarinetConfig;
|
|
24
|
-
async function getContractsFromClarinet(folder, accounts) {
|
|
25
|
-
const clarinetConfig = await getClarinetConfig(folder);
|
|
26
|
-
const deployerAddress = accounts.deployer.address;
|
|
27
|
-
const contracts = Object.entries(clarinetConfig.contracts).map(([contractName, info]) => {
|
|
28
|
-
const file = info.path.replace(/^contracts\//, '');
|
|
29
|
-
return {
|
|
30
|
-
file,
|
|
31
|
-
address: deployerAddress,
|
|
32
|
-
};
|
|
33
|
-
});
|
|
34
|
-
return contracts;
|
|
35
|
-
}
|
|
36
|
-
exports.getContractsFromClarinet = getContractsFromClarinet;
|
|
37
|
-
async function getClarinetAccounts(folder) {
|
|
38
|
-
const devConfig = await getClarinetDevConfig(folder);
|
|
39
|
-
const accountEntries = await Promise.all(Object.entries(devConfig.accounts).map(async ([key, info]) => {
|
|
40
|
-
const wallet = await wallet_sdk_1.generateWallet({
|
|
41
|
-
secretKey: info.mnemonic,
|
|
42
|
-
password: 'password',
|
|
43
|
-
});
|
|
44
|
-
const [account] = wallet.accounts;
|
|
45
|
-
const address = wallet_sdk_1.getStxAddress({ account });
|
|
46
|
-
return [
|
|
47
|
-
key,
|
|
48
|
-
{
|
|
49
|
-
...info,
|
|
50
|
-
address,
|
|
51
|
-
},
|
|
52
|
-
];
|
|
53
|
-
}));
|
|
54
|
-
const accounts = Object.fromEntries(accountEntries);
|
|
55
|
-
return accounts;
|
|
56
|
-
}
|
|
57
|
-
exports.getClarinetAccounts = getClarinetAccounts;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Contract = void 0;
|
|
4
|
-
const command_1 = require("@oclif/command");
|
|
5
|
-
const utils_1 = require("../utils");
|
|
6
|
-
class Contract extends command_1.Command {
|
|
7
|
-
async run() {
|
|
8
|
-
const { argv, flags } = this.parse(Contract);
|
|
9
|
-
const [contractFile] = argv;
|
|
10
|
-
await utils_1.generateFilesForContract({
|
|
11
|
-
contractFile,
|
|
12
|
-
outputFolder: flags.output,
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
exports.Contract = Contract;
|
|
17
|
-
Contract.description = `Generate files for a single contract`;
|
|
18
|
-
Contract.strict = true;
|
|
19
|
-
Contract.hidden = true;
|
|
20
|
-
Contract.flags = {
|
|
21
|
-
help: command_1.flags.help({ char: 'h' }),
|
|
22
|
-
output: command_1.flags.string({
|
|
23
|
-
char: 'o',
|
|
24
|
-
description: 'Output destination folder',
|
|
25
|
-
default: 'clarion',
|
|
26
|
-
}),
|
|
27
|
-
};
|
|
28
|
-
Contract.args = [
|
|
29
|
-
{
|
|
30
|
-
name: 'contract',
|
|
31
|
-
description: 'The file path for your contract',
|
|
32
|
-
},
|
|
33
|
-
];
|