@clarigen/test 1.0.3 → 1.0.16-alpha.0
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/index.d.ts +20 -89
- package/dist/index.js +2 -443
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -443
- package/dist/index.mjs.map +1 -0
- package/package.json +16 -15
- package/README.md +0 -178
- package/contracts/test-utils.clar +0 -11
package/dist/index.d.ts
CHANGED
|
@@ -1,94 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
export { Allocation, createClarityBin, evalJson, executeJson } from '@clarigen/native-bin';
|
|
4
|
-
import { ClarityValue, ResponseCV } from 'micro-stacks/clarity';
|
|
5
|
-
import { StacksNetworkVersion } from 'micro-stacks/crypto';
|
|
6
|
-
import { IntegerType } from 'micro-stacks/common';
|
|
1
|
+
import { UnknownArgs, ContractCallTyped, OkType, ErrType } from '@clarigen/core';
|
|
2
|
+
import { Simnet, ParsedTransactionResult } from '@hirosystems/clarinet-sdk';
|
|
7
3
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
clarityValue: ClarityValue;
|
|
11
|
-
logs: string[];
|
|
12
|
-
costs: Costs;
|
|
4
|
+
declare global {
|
|
5
|
+
var simnet: Simnet;
|
|
13
6
|
}
|
|
14
|
-
|
|
15
|
-
value:
|
|
16
|
-
response: ResponseCV;
|
|
17
|
-
isOk: boolean;
|
|
18
|
-
logs: string[];
|
|
19
|
-
costs: Costs;
|
|
20
|
-
}
|
|
21
|
-
interface PublicResultErr<T> extends PublicResultBase<T> {
|
|
22
|
-
value: T;
|
|
23
|
-
isOk: false;
|
|
24
|
-
}
|
|
25
|
-
interface PublicResultOk<T> extends PublicResultBase<T> {
|
|
26
|
-
value: T;
|
|
27
|
-
isOk: true;
|
|
28
|
-
events: CoreNodeEvent[];
|
|
29
|
-
assets: ResultAssets;
|
|
30
|
-
prints: any[];
|
|
31
|
-
}
|
|
32
|
-
declare type PublicResult<R> = PublicResultOk<R> | PublicResultErr<R>;
|
|
33
|
-
|
|
34
|
-
declare type Account = Omit<ClarinetAccount, 'balance'> & {
|
|
35
|
-
balance: number;
|
|
7
|
+
type TransactionResult<R> = ParsedTransactionResult & {
|
|
8
|
+
value: R;
|
|
36
9
|
};
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
clarityBin: NativeClarityBinProvider;
|
|
10
|
+
declare function txOk<A extends UnknownArgs, R>(tx: ContractCallTyped<A, R>, sender: string): TransactionResult<OkType<R>>;
|
|
11
|
+
declare function txErr<A extends UnknownArgs, R>(tx: ContractCallTyped<A, R>, sender: string): TransactionResult<ErrType<R>>;
|
|
12
|
+
declare function tx<A extends UnknownArgs, R>(tx: ContractCallTyped<A, R>, sender: string): TransactionResult<R>;
|
|
13
|
+
declare function ro<A extends UnknownArgs, R>(tx: ContractCallTyped<A, R>, sender: string): R;
|
|
14
|
+
declare function roOk<A extends UnknownArgs, R>(tx: ContractCallTyped<A, R>, sender: string): OkType<R>;
|
|
15
|
+
declare function roErr<A extends UnknownArgs, R>(tx: ContractCallTyped<A, R>, sender: string): ErrType<R>;
|
|
16
|
+
declare const chain: {
|
|
17
|
+
txOk: typeof txOk;
|
|
18
|
+
txErr: typeof txErr;
|
|
19
|
+
tx: typeof tx;
|
|
20
|
+
ro: typeof ro;
|
|
21
|
+
roOk: typeof roOk;
|
|
22
|
+
roErr: typeof roErr;
|
|
51
23
|
};
|
|
52
|
-
declare function getBlockHeight(provider: Provider): Promise<bigint>;
|
|
53
|
-
declare function mineBlocks(_blocks: IntegerType, provider: Provider): Promise<void>;
|
|
54
|
-
declare function getStxBalance(provider: Provider, account: string): Promise<bigint>;
|
|
55
|
-
|
|
56
|
-
declare function setupCoverage(dir: string): Promise<string>;
|
|
57
|
-
declare function finishCoverage(provider: NativeClarityBinProvider, dir: string): Promise<void>;
|
|
58
|
-
|
|
59
|
-
declare function makeRandomAddress(version?: StacksNetworkVersion): string;
|
|
60
|
-
|
|
61
|
-
interface FromContractsOptions {
|
|
62
|
-
accounts?: ClarinetAccounts;
|
|
63
|
-
clarityBin?: NativeClarityBinProvider;
|
|
64
|
-
coverageFolder?: string;
|
|
65
|
-
clarinetPath?: string;
|
|
66
|
-
}
|
|
67
|
-
interface FromContracts<T extends Contracts<any>> {
|
|
68
|
-
deployed: ContractInstances<T>;
|
|
69
|
-
provider: TestProvider;
|
|
70
|
-
}
|
|
71
|
-
declare type OkType<T> = T extends ResponseOk<infer Ok, unknown> ? Ok : never;
|
|
72
|
-
declare type ErrType<T> = T extends ResponseErr<unknown, infer Err> ? Err : never;
|
|
73
|
-
declare class TestProvider {
|
|
74
|
-
clarityBin: NativeClarityBinProvider;
|
|
75
|
-
coverageFolder?: string;
|
|
76
|
-
constructor(clarityBin: NativeClarityBinProvider);
|
|
77
|
-
static fromContracts<T extends Contracts<any>>(contracts: T, options?: FromContractsOptions): Promise<FromContracts<T>>;
|
|
78
|
-
static fromProject(simnet: Simnet, options?: FromContractsOptions): Promise<TestProvider>;
|
|
79
|
-
static fromFactory(contracts: ContractFactory<AllContracts>, options?: FromContractsOptions): Promise<TestProvider>;
|
|
80
|
-
ro<T>(tx: ContractCall<T>): Promise<ReadOnlyResult<T>>;
|
|
81
|
-
rov<T>(tx: ContractCall<T>): Promise<T>;
|
|
82
|
-
roOk<R extends Response<unknown, unknown>>(tx: ContractCall<R>): Promise<ReadOnlyResult<OkType<R>>>;
|
|
83
|
-
roErr<R extends Response<unknown, unknown>>(tx: ContractCall<R>): Promise<ReadOnlyResult<ErrType<R>>>;
|
|
84
|
-
rovOk<R extends Response<unknown, unknown>>(tx: ContractCall<R>): Promise<OkType<R>>;
|
|
85
|
-
rovErr<R extends Response<unknown, unknown>>(tx: ContractCall<R>): Promise<ErrType<R>>;
|
|
86
|
-
tx<R extends Response<unknown, unknown>>(tx: ContractCall<R>, senderAddress: string): Promise<PublicResult<R>>;
|
|
87
|
-
txOk<R extends Response<unknown, unknown>>(tx: ContractCall<R>, senderAddress: string): Promise<PublicResultOk<OkType<R>>>;
|
|
88
|
-
txErr<R extends Response<unknown, unknown>>(tx: ContractCall<R>, senderAddress: string): Promise<PublicResultErr<ErrType<R>>>;
|
|
89
|
-
evalCode<T>(code: string, contractAddress?: string): Promise<ReadOnlyResult<T>>;
|
|
90
|
-
eval<T>(code: string, contractAddress?: string): Promise<T>;
|
|
91
|
-
mapGet<T extends ContractCalls.Map<any, Val>, Val>(map: T): Promise<Val | null>;
|
|
92
|
-
}
|
|
93
24
|
|
|
94
|
-
export {
|
|
25
|
+
export { TransactionResult, chain, ro, roErr, roOk, tx, txErr, txOk };
|
package/dist/index.js
CHANGED
|
@@ -1,443 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var
|
|
2
|
-
|
|
3
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
-
var __spreadValues = (a, b) => {
|
|
9
|
-
for (var prop in b || (b = {}))
|
|
10
|
-
if (__hasOwnProp.call(b, prop))
|
|
11
|
-
__defNormalProp(a, prop, b[prop]);
|
|
12
|
-
if (__getOwnPropSymbols)
|
|
13
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
-
if (__propIsEnum.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
}
|
|
17
|
-
return a;
|
|
18
|
-
};
|
|
19
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
|
|
21
|
-
// src/index.ts
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
var _nativebin = require('@clarigen/native-bin');
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
var _core = require('@clarigen/core');
|
|
31
|
-
|
|
32
|
-
// src/utils/index.ts
|
|
33
|
-
var _crypto = require('micro-stacks/crypto');
|
|
34
|
-
var _transactions = require('micro-stacks/transactions');
|
|
35
|
-
|
|
36
|
-
// src/utils/util-contract.ts
|
|
37
|
-
var _clarity = require('micro-stacks/clarity');
|
|
38
|
-
var _path = require('path');
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
var _common = require('micro-stacks/common');
|
|
42
|
-
var UTIL_CONTRACT_ID = "ST000000000000000000002AMW42H.clarigen-test-utils";
|
|
43
|
-
async function deployUtilContract(clarityBin) {
|
|
44
|
-
let contractFilePath = _path.join.call(void 0, __dirname, "..", "..", "contracts", "test-utils.clar");
|
|
45
|
-
if (__dirname.includes("dist")) {
|
|
46
|
-
contractFilePath = _path.join.call(void 0, __dirname, "..", "contracts", "test-utils.clar");
|
|
47
|
-
}
|
|
48
|
-
await _nativebin.deployContract.call(void 0, {
|
|
49
|
-
contractIdentifier: UTIL_CONTRACT_ID,
|
|
50
|
-
provider: clarityBin,
|
|
51
|
-
contractFilePath
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
function getBin(provider) {
|
|
55
|
-
return "clarityBin" in provider ? provider.clarityBin : provider;
|
|
56
|
-
}
|
|
57
|
-
async function getBlockHeight(provider) {
|
|
58
|
-
const bin = getBin(provider);
|
|
59
|
-
const { output_serialized } = await _nativebin.evalJson.call(void 0, {
|
|
60
|
-
contractAddress: UTIL_CONTRACT_ID,
|
|
61
|
-
functionName: "get-block-height",
|
|
62
|
-
args: [],
|
|
63
|
-
provider: bin
|
|
64
|
-
});
|
|
65
|
-
const outputCV = _clarity.hexToCV.call(void 0, output_serialized);
|
|
66
|
-
const blockHeight = _core.cvToValue.call(void 0, outputCV);
|
|
67
|
-
return blockHeight;
|
|
68
|
-
}
|
|
69
|
-
async function mineBlock(provider) {
|
|
70
|
-
const bin = getBin(provider);
|
|
71
|
-
await _nativebin.executeJson.call(void 0, {
|
|
72
|
-
contractAddress: UTIL_CONTRACT_ID,
|
|
73
|
-
functionName: "mine-block",
|
|
74
|
-
args: [],
|
|
75
|
-
provider: bin,
|
|
76
|
-
senderAddress: "ST000000000000000000002AMW42H"
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
async function mineBlocks(_blocks, provider) {
|
|
80
|
-
const blocks = _common.intToBigInt.call(void 0, _blocks);
|
|
81
|
-
for (let index = 0; index < blocks; index++) {
|
|
82
|
-
await mineBlock(provider);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
async function getStxBalance(provider, account) {
|
|
86
|
-
const bin = getBin(provider);
|
|
87
|
-
const { output_serialized } = await _nativebin.evalJson.call(void 0, {
|
|
88
|
-
contractAddress: UTIL_CONTRACT_ID,
|
|
89
|
-
functionName: "get-stx-balance",
|
|
90
|
-
args: [`'${account}`],
|
|
91
|
-
provider: bin
|
|
92
|
-
});
|
|
93
|
-
const outputCV = _clarity.hexToCV.call(void 0, output_serialized);
|
|
94
|
-
const balance = _core.cvToValue.call(void 0, outputCV);
|
|
95
|
-
return balance;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// src/utils/coverage.ts
|
|
99
|
-
var _promises = require('fs/promises');
|
|
100
|
-
|
|
101
|
-
async function setupCoverage(dir) {
|
|
102
|
-
const dirName = _path.resolve.call(void 0, process.cwd(), "coverage");
|
|
103
|
-
try {
|
|
104
|
-
await _promises.mkdir.call(void 0, dirName);
|
|
105
|
-
} catch (error) {
|
|
106
|
-
}
|
|
107
|
-
const files = await _promises.readdir.call(void 0, dirName);
|
|
108
|
-
const removals = files.map((file) => {
|
|
109
|
-
return _promises.unlink.call(void 0, _path.join.call(void 0, dirName, file));
|
|
110
|
-
});
|
|
111
|
-
await Promise.all(removals);
|
|
112
|
-
return dirName;
|
|
113
|
-
}
|
|
114
|
-
async function finishCoverage(provider, dir) {
|
|
115
|
-
const lcovFile = _path.join.call(void 0, dir, "clarigen.lcov");
|
|
116
|
-
await provider.runCommand(["make_lcov", dir, lcovFile]);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// src/utils/index.ts
|
|
120
|
-
function makeRandomAddress(version = _crypto.StacksNetworkVersion.testnetP2PKH) {
|
|
121
|
-
const privateKey = _transactions.makeRandomPrivKey.call(void 0, );
|
|
122
|
-
const publicKey = _transactions.getPublicKeyFromStacksPrivateKey.call(void 0, privateKey);
|
|
123
|
-
const address = _crypto.publicKeyToStxAddress.call(void 0, publicKey.data, version);
|
|
124
|
-
return address;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// src/utils/pure.ts
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
function getPrints(events) {
|
|
147
|
-
return _core.filterEvents.call(void 0, events, _core.CoreNodeEventType.ContractEvent).map((e) => {
|
|
148
|
-
const hex = e.contract_event.raw_value;
|
|
149
|
-
const cv = _clarity.hexToCV.call(void 0, hex);
|
|
150
|
-
return _core.cvToValue.call(void 0, cv);
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
function formatArguments(args) {
|
|
154
|
-
return args.map((arg) => _core.cvToString.call(void 0, arg));
|
|
155
|
-
}
|
|
156
|
-
function getIdentifier(tx2) {
|
|
157
|
-
return `${tx2.contractAddress}.${tx2.contractName}`;
|
|
158
|
-
}
|
|
159
|
-
function getLogs(stderr) {
|
|
160
|
-
if (stderr === "")
|
|
161
|
-
return [];
|
|
162
|
-
return stderr.split("\n").map((line) => line.slice(62));
|
|
163
|
-
}
|
|
164
|
-
function makeEvalResult(result) {
|
|
165
|
-
const resultCV = _clarity.hexToCV.call(void 0, result.output_serialized);
|
|
166
|
-
const value = _core.cvToValue.call(void 0, resultCV, true);
|
|
167
|
-
return {
|
|
168
|
-
value,
|
|
169
|
-
clarityValue: resultCV,
|
|
170
|
-
logs: getLogs(result.stderr),
|
|
171
|
-
costs: result.costs
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
async function ro({
|
|
175
|
-
tx: tx2,
|
|
176
|
-
bin,
|
|
177
|
-
coverageFolder
|
|
178
|
-
}) {
|
|
179
|
-
const result = await _nativebin.evalJson.call(void 0, {
|
|
180
|
-
functionName: tx2.function.name,
|
|
181
|
-
args: formatArguments(tx2.functionArgs),
|
|
182
|
-
contractAddress: getIdentifier(tx2),
|
|
183
|
-
provider: bin,
|
|
184
|
-
coverageFolder
|
|
185
|
-
});
|
|
186
|
-
return makeEvalResult(result);
|
|
187
|
-
}
|
|
188
|
-
async function evalCode({
|
|
189
|
-
contractAddress,
|
|
190
|
-
code,
|
|
191
|
-
bin,
|
|
192
|
-
coverageFolder
|
|
193
|
-
}) {
|
|
194
|
-
const result = await _nativebin.evalRaw.call(void 0, {
|
|
195
|
-
contractAddress,
|
|
196
|
-
code,
|
|
197
|
-
provider: bin,
|
|
198
|
-
coverageFolder
|
|
199
|
-
});
|
|
200
|
-
return makeEvalResult(result);
|
|
201
|
-
}
|
|
202
|
-
async function tx({
|
|
203
|
-
tx: tx2,
|
|
204
|
-
senderAddress,
|
|
205
|
-
bin,
|
|
206
|
-
coverageFolder
|
|
207
|
-
}) {
|
|
208
|
-
const result = await _nativebin.executeJson.call(void 0, {
|
|
209
|
-
contractAddress: getIdentifier(tx2),
|
|
210
|
-
senderAddress,
|
|
211
|
-
provider: bin,
|
|
212
|
-
functionName: tx2.function.name,
|
|
213
|
-
args: formatArguments(tx2.functionArgs),
|
|
214
|
-
coverageFolder
|
|
215
|
-
});
|
|
216
|
-
const resultCV = _clarity.hexToCV.call(void 0, result.output_serialized);
|
|
217
|
-
const value = _core.cvToValue.call(void 0, resultCV);
|
|
218
|
-
const resp = result.success ? _core.ok.call(void 0, value) : _core.err.call(void 0, value);
|
|
219
|
-
const baseReturn = {
|
|
220
|
-
logs: getLogs(result.stderr),
|
|
221
|
-
costs: result.costs,
|
|
222
|
-
value: resp
|
|
223
|
-
};
|
|
224
|
-
if (result.success) {
|
|
225
|
-
return __spreadProps(__spreadValues({}, baseReturn), {
|
|
226
|
-
isOk: true,
|
|
227
|
-
response: _clarity.responseOkCV.call(void 0, resultCV),
|
|
228
|
-
assets: result.assets,
|
|
229
|
-
events: result.events,
|
|
230
|
-
prints: getPrints(result.events)
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
return __spreadProps(__spreadValues({}, baseReturn), {
|
|
234
|
-
isOk: false,
|
|
235
|
-
response: _clarity.responseErrorCV.call(void 0, resultCV)
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
async function mapGet({
|
|
239
|
-
map,
|
|
240
|
-
bin
|
|
241
|
-
}) {
|
|
242
|
-
const code = `(map-get? ${map.map.name} ${_core.cvToString.call(void 0, map.key)})`;
|
|
243
|
-
const result = await evalCode({
|
|
244
|
-
contractAddress: getIdentifier(map),
|
|
245
|
-
code,
|
|
246
|
-
bin
|
|
247
|
-
});
|
|
248
|
-
return result.value;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// src/index.ts
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
// src/utils/test-factory.ts
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
function testFactory(project) {
|
|
259
|
-
return _core.projectFactory.call(void 0, project, "simnet");
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// src/index.ts
|
|
263
|
-
|
|
264
|
-
var TestProvider = class {
|
|
265
|
-
constructor(clarityBin) {
|
|
266
|
-
this.clarityBin = clarityBin;
|
|
267
|
-
}
|
|
268
|
-
static async fromContracts(contracts, options = {}) {
|
|
269
|
-
const clarityBin = options.clarityBin || await _nativebin.createClarityBin.call(void 0, {
|
|
270
|
-
allocations: options.accounts
|
|
271
|
-
});
|
|
272
|
-
const instances = {};
|
|
273
|
-
let coverageFolder = options.coverageFolder;
|
|
274
|
-
if (process.env.CLARIGEN_COVERAGE) {
|
|
275
|
-
coverageFolder = _path.resolve.call(void 0, process.cwd(), "coverage");
|
|
276
|
-
}
|
|
277
|
-
await deployUtilContract(clarityBin);
|
|
278
|
-
for (const k in contracts) {
|
|
279
|
-
if (Object.prototype.hasOwnProperty.call(contracts, k)) {
|
|
280
|
-
const contract = contracts[k];
|
|
281
|
-
const identifier = _core.getContractIdentifier.call(void 0, contract);
|
|
282
|
-
await _nativebin.deployContract.call(void 0, {
|
|
283
|
-
contractIdentifier: identifier,
|
|
284
|
-
contractFilePath: contract.contractFile,
|
|
285
|
-
provider: clarityBin,
|
|
286
|
-
coverageFolder
|
|
287
|
-
});
|
|
288
|
-
const instance = contract.contract(contract.address, contract.name);
|
|
289
|
-
instances[k] = {
|
|
290
|
-
identifier: _core.getContractIdentifier.call(void 0, contract),
|
|
291
|
-
contract: instance
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
const provider = new this(clarityBin);
|
|
296
|
-
provider.coverageFolder = coverageFolder;
|
|
297
|
-
return {
|
|
298
|
-
deployed: instances,
|
|
299
|
-
provider
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
static async fromProject(simnet, options = {}) {
|
|
303
|
-
const allocations = Object.fromEntries(Object.entries(simnet.accounts).map(([name, account]) => {
|
|
304
|
-
return [name, __spreadProps(__spreadValues({}, account), { balance: BigInt(account.balance) })];
|
|
305
|
-
}));
|
|
306
|
-
const clarityBin = options.clarityBin || await _nativebin.createClarityBin.call(void 0, {
|
|
307
|
-
allocations
|
|
308
|
-
});
|
|
309
|
-
let coverageFolder = options.coverageFolder;
|
|
310
|
-
if (process.env.CLARIGEN_COVERAGE) {
|
|
311
|
-
coverageFolder = _path.resolve.call(void 0, process.cwd(), "coverage");
|
|
312
|
-
}
|
|
313
|
-
await deployUtilContract(clarityBin);
|
|
314
|
-
for (const contract of simnet.deployment) {
|
|
315
|
-
let contractFilePath = contract.file;
|
|
316
|
-
if (options.clarinetPath) {
|
|
317
|
-
contractFilePath = _path.resolve.call(void 0, process.cwd(), options.clarinetPath, contractFilePath);
|
|
318
|
-
}
|
|
319
|
-
await _nativebin.deployContract.call(void 0, {
|
|
320
|
-
contractIdentifier: contract.identifier,
|
|
321
|
-
contractFilePath,
|
|
322
|
-
provider: clarityBin,
|
|
323
|
-
coverageFolder
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
const provider = new this(clarityBin);
|
|
327
|
-
provider.coverageFolder = coverageFolder;
|
|
328
|
-
return provider;
|
|
329
|
-
}
|
|
330
|
-
static async fromFactory(contracts, options = {}) {
|
|
331
|
-
const clarityBin = options.clarityBin || await _nativebin.createClarityBin.call(void 0, {
|
|
332
|
-
allocations: options.accounts
|
|
333
|
-
});
|
|
334
|
-
let coverageFolder = options.coverageFolder;
|
|
335
|
-
if (process.env.CLARIGEN_COVERAGE) {
|
|
336
|
-
coverageFolder = _path.resolve.call(void 0, process.cwd(), "coverage");
|
|
337
|
-
}
|
|
338
|
-
await deployUtilContract(clarityBin);
|
|
339
|
-
for (const k in contracts) {
|
|
340
|
-
if (Object.prototype.hasOwnProperty.call(contracts, k)) {
|
|
341
|
-
const contract = contracts[k];
|
|
342
|
-
let contractFilePath = contract.contractFile;
|
|
343
|
-
if (options.clarinetPath) {
|
|
344
|
-
contractFilePath = _path.resolve.call(void 0, process.cwd(), options.clarinetPath, contractFilePath);
|
|
345
|
-
}
|
|
346
|
-
if (typeof contractFilePath === "undefined") {
|
|
347
|
-
throw new Error("Cannot setup @clarigen/test - missing contract file.");
|
|
348
|
-
}
|
|
349
|
-
await _nativebin.deployContract.call(void 0, {
|
|
350
|
-
contractIdentifier: contract.identifier,
|
|
351
|
-
contractFilePath,
|
|
352
|
-
provider: clarityBin,
|
|
353
|
-
coverageFolder
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
const provider = new this(clarityBin);
|
|
358
|
-
provider.coverageFolder = coverageFolder;
|
|
359
|
-
return provider;
|
|
360
|
-
}
|
|
361
|
-
ro(tx2) {
|
|
362
|
-
return ro({ tx: tx2, bin: this.clarityBin, coverageFolder: this.coverageFolder });
|
|
363
|
-
}
|
|
364
|
-
async rov(tx2) {
|
|
365
|
-
const result = await this.ro(tx2);
|
|
366
|
-
return result.value;
|
|
367
|
-
}
|
|
368
|
-
async roOk(tx2) {
|
|
369
|
-
const result = await this.ro(tx2);
|
|
370
|
-
const value = _core.expectOk.call(void 0, result.value);
|
|
371
|
-
return __spreadProps(__spreadValues({}, result), {
|
|
372
|
-
value
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
async roErr(tx2) {
|
|
376
|
-
const result = await this.ro(tx2);
|
|
377
|
-
const value = _core.expectErr.call(void 0, result.value);
|
|
378
|
-
return __spreadProps(__spreadValues({}, result), {
|
|
379
|
-
value
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
async rovOk(tx2) {
|
|
383
|
-
return (await this.roOk(tx2)).value;
|
|
384
|
-
}
|
|
385
|
-
async rovErr(tx2) {
|
|
386
|
-
return (await this.roErr(tx2)).value;
|
|
387
|
-
}
|
|
388
|
-
tx(tx2, senderAddress) {
|
|
389
|
-
return tx({
|
|
390
|
-
tx: tx2,
|
|
391
|
-
senderAddress,
|
|
392
|
-
bin: this.clarityBin,
|
|
393
|
-
coverageFolder: this.coverageFolder
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
async txOk(tx2, senderAddress) {
|
|
397
|
-
const result = await this.tx(tx2, senderAddress);
|
|
398
|
-
const value = _core.expectOk.call(void 0, result.value);
|
|
399
|
-
if (!result.isOk)
|
|
400
|
-
throw new Error(`Expected OK, received error: ${String(result.value)}`);
|
|
401
|
-
return __spreadProps(__spreadValues({}, result), {
|
|
402
|
-
value
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
async txErr(tx2, senderAddress) {
|
|
406
|
-
const result = await this.tx(tx2, senderAddress);
|
|
407
|
-
const value = _core.expectErr.call(void 0, result.value);
|
|
408
|
-
if (result.isOk)
|
|
409
|
-
throw new Error(`Expected Err, received ok: ${String(result.value)}`);
|
|
410
|
-
return __spreadProps(__spreadValues({}, result), {
|
|
411
|
-
value
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
evalCode(code, contractAddress = UTIL_CONTRACT_ID) {
|
|
415
|
-
return evalCode({
|
|
416
|
-
contractAddress,
|
|
417
|
-
code,
|
|
418
|
-
bin: this.clarityBin,
|
|
419
|
-
coverageFolder: this.coverageFolder
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
async eval(code, contractAddress = UTIL_CONTRACT_ID) {
|
|
423
|
-
const result = await this.evalCode(code, contractAddress);
|
|
424
|
-
return result.value;
|
|
425
|
-
}
|
|
426
|
-
mapGet(map) {
|
|
427
|
-
return mapGet({ map, bin: this.clarityBin });
|
|
428
|
-
}
|
|
429
|
-
};
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
exports.Allocation = _nativebin.Allocation; exports.TestProvider = TestProvider; exports.createClarityBin = _nativebin.createClarityBin; exports.evalJson = _nativebin.evalJson; exports.executeJson = _nativebin.executeJson; exports.finishCoverage = finishCoverage; exports.getBlockHeight = getBlockHeight; exports.getStxBalance = getStxBalance; exports.makeRandomAddress = makeRandomAddress; exports.mineBlocks = mineBlocks; exports.setupCoverage = setupCoverage; exports.testFactory = testFactory;
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var d=Object.defineProperty,R=Object.defineProperties;var m=Object.getOwnPropertyDescriptors;var u=Object.getOwnPropertySymbols;var C=Object.prototype.hasOwnProperty,f=Object.prototype.propertyIsEnumerable;var p=(n,r,e)=>r in n?d(n,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[r]=e,i=(n,r)=>{for(var e in r||(r={}))C.call(r,e)&&p(n,e,r[e]);if(u)for(var e of u(r))f.call(r,e)&&p(n,e,r[e]);return n},l=(n,r)=>R(n,m(r));var _core = require('@clarigen/core');var _transactions = require('@stacks/transactions');var _clarity = require('micro-stacks/clarity');function s(n){return _transactions.deserializeCV.call(void 0, _clarity.serializeCV.call(void 0, n))}function V(n){return _clarity.deserializeCV.call(void 0, _transactions.serializeCV.call(void 0, n))}function c(n,r){let e=_core.cvToValue.call(void 0, V(n),!0);if(typeof r<"u"&&"isOk"in e){let a=e,t=a.value;if(r&&!a.isOk)throw new Error(`Tx result failed. Expected OK, received ERR ${t}.`);if(r===!1&&a.isOk)throw new Error(`Tx result failed. Expected ERR, received OK ${t}.`);return t}return e}function k(n,r){let e=n.functionArgs.map(s),a=`${n.contractAddress}.${n.contractName}`,t=simnet.callPublicFn(a,n.function.name,e,r),o=c(t.result,!0);return l(i({},t),{value:o})}function $(n,r){let e=n.functionArgs.map(s),a=`${n.contractAddress}.${n.contractName}`,t=simnet.callPublicFn(a,n.function.name,e,r),o=c(t.result,!1);return l(i({},t),{value:o})}function w(n,r){let e=n.functionArgs.map(s),a=`${n.contractAddress}.${n.contractName}`,t=simnet.callPublicFn(a,n.function.name,e,r),o=c(t.result);return l(i({},t),{value:o})}function E(n,r){let e=n.functionArgs.map(s),a=`${n.contractAddress}.${n.contractName}`,t=simnet.callReadOnlyFn(a,n.function.name,e,r);return c(t.result)}function O(n,r){let e=n.functionArgs.map(s),a=`${n.contractAddress}.${n.contractName}`,t=simnet.callReadOnlyFn(a,n.function.name,e,r);return c(t.result,!0)}function S(n,r){let e=n.functionArgs.map(s),a=`${n.contractAddress}.${n.contractName}`,t=simnet.callReadOnlyFn(a,n.function.name,e,r);return c(t.result,!1)}var j={txOk:k,txErr:$,tx:w,ro:E,roOk:O,roErr:S};exports.chain = j; exports.ro = E; exports.roErr = S; exports.roOk = O; exports.tx = w; exports.txErr = $; exports.txOk = k;
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/index.ts"],"names":[],"mappings":"6aAAA,2CACA,sEAMA,sEAQO,WAAqB,EAAyC,CACnE,MAAO,GAAkB,EAAc,CAAK,CAAC,CAC/C,CAEO,WAAuB,EAAyC,CACrE,MAAO,GAAgB,EAAgB,CAAK,CAAC,CAC/C,CAEO,WAA6B,EAA0B,EAAuB,CACnF,GAAM,GAAQ,EAAU,EAAc,CAAM,EAAG,EAAI,EACnD,GAAI,MAAO,GAAa,KAAe,QAAU,GAAO,CACtD,GAAM,GAAW,EACX,EAAQ,EAAS,MACvB,GAAI,GAAY,CAAC,EAAS,KACxB,KAAM,IAAI,OAAM,+CAA+C,IAAQ,EAEzE,GAAI,IAAa,IAAS,EAAS,KACjC,KAAM,IAAI,OAAM,+CAA+C,IAAQ,EAEzE,MAAO,EACT,CACA,MAAO,EACT,CCzBO,WACL,EACA,EAC8B,CAC9B,GAAM,GAAO,EAAG,aAAa,IAAI,CAAW,EACtC,EAAa,GAAG,EAAG,mBAAmB,EAAG,eACzC,EAAU,OAAO,aAAa,EAAY,EAAG,SAAS,KAAM,EAAM,CAAM,EACxE,EAAQ,EAA4B,EAAQ,OAAQ,EAAI,EAE9D,MAAO,QACF,GADE,CAEL,OACF,EACF,CAEO,WACL,EACA,EAC+B,CAC/B,GAAM,GAAO,EAAG,aAAa,IAAI,CAAW,EACtC,EAAa,GAAG,EAAG,mBAAmB,EAAG,eACzC,EAAU,OAAO,aAAa,EAAY,EAAG,SAAS,KAAM,EAAM,CAAM,EACxE,EAAQ,EAA6B,EAAQ,OAAQ,EAAK,EAEhE,MAAO,QACF,GADE,CAEL,OACF,EACF,CAEO,WACL,EACA,EACsB,CACtB,GAAM,GAAO,EAAG,aAAa,IAAI,CAAW,EACtC,EAAa,GAAG,EAAG,mBAAmB,EAAG,eACzC,EAAU,OAAO,aAAa,EAAY,EAAG,SAAS,KAAM,EAAM,CAAM,EACxE,EAAQ,EAAoB,EAAQ,MAAM,EAEhD,MAAO,QACF,GADE,CAEL,OACF,EACF,CAEO,WAAsC,EAA6B,EAAmB,CAC3F,GAAM,GAAO,EAAG,aAAa,IAAI,CAAW,EACtC,EAAa,GAAG,EAAG,mBAAmB,EAAG,eACzC,EAAU,OAAO,eAAe,EAAY,EAAG,SAAS,KAAM,EAAM,CAAM,EAGhF,MAFc,GAAoB,EAAQ,MAAM,CAGlD,CAEO,WACL,EACA,EACW,CACX,GAAM,GAAO,EAAG,aAAa,IAAI,CAAW,EACtC,EAAa,GAAG,EAAG,mBAAmB,EAAG,eACzC,EAAU,OAAO,eAAe,EAAY,EAAG,SAAS,KAAM,EAAM,CAAM,EAGhF,MAFc,GAA4B,EAAQ,OAAQ,EAAI,CAGhE,CAEO,WACL,EACA,EACY,CACZ,GAAM,GAAO,EAAG,aAAa,IAAI,CAAW,EACtC,EAAa,GAAG,EAAG,mBAAmB,EAAG,eACzC,EAAU,OAAO,eAAe,EAAY,EAAG,SAAS,KAAM,EAAM,CAAM,EAGhF,MAFc,GAA6B,EAAQ,OAAQ,EAAK,CAGlE,CAGO,GAAM,GAAQ,CACnB,OACA,QACA,KACA,KACA,OACA,OACF","sourcesContent":["import { Response, cvToValue } from '@clarigen/core';\nimport {\n ClarityValue as HiroClarityValue,\n deserializeCV as deserializeCVHiro,\n serializeCV as serializeCVHiro,\n StandardPrincipalCV as HiroPrincipalCV,\n} from '@stacks/transactions';\nimport {\n ClarityValue as MSClarityValue,\n StandardPrincipalCV as MSPrincipalCV,\n serializeCV as serializeCVMS,\n deserializeCV as deserializeCVMS,\n ClarityAbiFunction,\n} from 'micro-stacks/clarity';\n\nexport function cvConvertMS(value: MSClarityValue): HiroClarityValue {\n return deserializeCVHiro(serializeCVMS(value));\n}\n\nexport function cvConvertHiro(value: HiroClarityValue): MSClarityValue {\n return deserializeCVMS(serializeCVHiro(value));\n}\n\nexport function validateResponse<T>(result: HiroClarityValue, expectOk?: boolean): T {\n const value = cvToValue(cvConvertHiro(result), true);\n if (typeof expectOk !== 'undefined' && 'isOk' in value) {\n const response = value as Response<unknown, unknown>;\n const inner = response.value;\n if (expectOk && !response.isOk) {\n throw new Error(`Tx result failed. Expected OK, received ERR ${inner}.`);\n }\n if (expectOk === false && response.isOk) {\n throw new Error(`Tx result failed. Expected ERR, received OK ${inner}.`);\n }\n return inner as T;\n }\n return value;\n}\n","import { ContractCallTyped, ErrType, OkType, UnknownArgs } from '@clarigen/core';\nimport { Simnet, ParsedTransactionResult } from '@hirosystems/clarinet-sdk';\nimport { cvConvertMS, validateResponse } from './utils';\n\ndeclare global {\n var simnet: Simnet;\n}\n\nexport type TransactionResult<R> = ParsedTransactionResult & {\n value: R;\n};\n\nexport function txOk<A extends UnknownArgs, R>(\n tx: ContractCallTyped<A, R>,\n sender: string\n): TransactionResult<OkType<R>> {\n const args = tx.functionArgs.map(cvConvertMS);\n const contractId = `${tx.contractAddress}.${tx.contractName}`;\n const receipt = simnet.callPublicFn(contractId, tx.function.name, args, sender);\n const value = validateResponse<OkType<R>>(receipt.result, true);\n\n return {\n ...receipt,\n value,\n };\n}\n\nexport function txErr<A extends UnknownArgs, R>(\n tx: ContractCallTyped<A, R>,\n sender: string\n): TransactionResult<ErrType<R>> {\n const args = tx.functionArgs.map(cvConvertMS);\n const contractId = `${tx.contractAddress}.${tx.contractName}`;\n const receipt = simnet.callPublicFn(contractId, tx.function.name, args, sender);\n const value = validateResponse<ErrType<R>>(receipt.result, false);\n\n return {\n ...receipt,\n value,\n };\n}\n\nexport function tx<A extends UnknownArgs, R>(\n tx: ContractCallTyped<A, R>,\n sender: string\n): TransactionResult<R> {\n const args = tx.functionArgs.map(cvConvertMS);\n const contractId = `${tx.contractAddress}.${tx.contractName}`;\n const receipt = simnet.callPublicFn(contractId, tx.function.name, args, sender);\n const value = validateResponse<R>(receipt.result);\n\n return {\n ...receipt,\n value,\n };\n}\n\nexport function ro<A extends UnknownArgs, R>(tx: ContractCallTyped<A, R>, sender: string): R {\n const args = tx.functionArgs.map(cvConvertMS);\n const contractId = `${tx.contractAddress}.${tx.contractName}`;\n const receipt = simnet.callReadOnlyFn(contractId, tx.function.name, args, sender);\n const value = validateResponse<R>(receipt.result);\n\n return value;\n}\n\nexport function roOk<A extends UnknownArgs, R>(\n tx: ContractCallTyped<A, R>,\n sender: string\n): OkType<R> {\n const args = tx.functionArgs.map(cvConvertMS);\n const contractId = `${tx.contractAddress}.${tx.contractName}`;\n const receipt = simnet.callReadOnlyFn(contractId, tx.function.name, args, sender);\n const value = validateResponse<OkType<R>>(receipt.result, true);\n\n return value;\n}\n\nexport function roErr<A extends UnknownArgs, R>(\n tx: ContractCallTyped<A, R>,\n sender: string\n): ErrType<R> {\n const args = tx.functionArgs.map(cvConvertMS);\n const contractId = `${tx.contractAddress}.${tx.contractName}`;\n const receipt = simnet.callReadOnlyFn(contractId, tx.function.name, args, sender);\n const value = validateResponse<ErrType<R>>(receipt.result, false);\n\n return value;\n}\n\n// Helper export for previous Deno-based tests\nexport const chain = {\n txOk,\n txErr,\n tx,\n ro,\n roOk,\n roErr,\n};\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,443 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
-
var __spreadValues = (a, b) => {
|
|
9
|
-
for (var prop in b || (b = {}))
|
|
10
|
-
if (__hasOwnProp.call(b, prop))
|
|
11
|
-
__defNormalProp(a, prop, b[prop]);
|
|
12
|
-
if (__getOwnPropSymbols)
|
|
13
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
-
if (__propIsEnum.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
}
|
|
17
|
-
return a;
|
|
18
|
-
};
|
|
19
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
|
|
21
|
-
// src/index.ts
|
|
22
|
-
import {
|
|
23
|
-
deployContract as deployContract2,
|
|
24
|
-
createClarityBin
|
|
25
|
-
} from "@clarigen/native-bin";
|
|
26
|
-
import {
|
|
27
|
-
getContractIdentifier,
|
|
28
|
-
expectOk,
|
|
29
|
-
expectErr
|
|
30
|
-
} from "@clarigen/core";
|
|
31
|
-
|
|
32
|
-
// src/utils/index.ts
|
|
33
|
-
import { publicKeyToStxAddress, StacksNetworkVersion } from "micro-stacks/crypto";
|
|
34
|
-
import { getPublicKeyFromStacksPrivateKey, makeRandomPrivKey } from "micro-stacks/transactions";
|
|
35
|
-
|
|
36
|
-
// src/utils/util-contract.ts
|
|
37
|
-
import { hexToCV } from "micro-stacks/clarity";
|
|
38
|
-
import { join } from "path";
|
|
39
|
-
import { cvToValue } from "@clarigen/core";
|
|
40
|
-
import { deployContract, evalJson, executeJson } from "@clarigen/native-bin";
|
|
41
|
-
import { intToBigInt } from "micro-stacks/common";
|
|
42
|
-
var UTIL_CONTRACT_ID = "ST000000000000000000002AMW42H.clarigen-test-utils";
|
|
43
|
-
async function deployUtilContract(clarityBin) {
|
|
44
|
-
let contractFilePath = join(__dirname, "..", "..", "contracts", "test-utils.clar");
|
|
45
|
-
if (__dirname.includes("dist")) {
|
|
46
|
-
contractFilePath = join(__dirname, "..", "contracts", "test-utils.clar");
|
|
47
|
-
}
|
|
48
|
-
await deployContract({
|
|
49
|
-
contractIdentifier: UTIL_CONTRACT_ID,
|
|
50
|
-
provider: clarityBin,
|
|
51
|
-
contractFilePath
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
function getBin(provider) {
|
|
55
|
-
return "clarityBin" in provider ? provider.clarityBin : provider;
|
|
56
|
-
}
|
|
57
|
-
async function getBlockHeight(provider) {
|
|
58
|
-
const bin = getBin(provider);
|
|
59
|
-
const { output_serialized } = await evalJson({
|
|
60
|
-
contractAddress: UTIL_CONTRACT_ID,
|
|
61
|
-
functionName: "get-block-height",
|
|
62
|
-
args: [],
|
|
63
|
-
provider: bin
|
|
64
|
-
});
|
|
65
|
-
const outputCV = hexToCV(output_serialized);
|
|
66
|
-
const blockHeight = cvToValue(outputCV);
|
|
67
|
-
return blockHeight;
|
|
68
|
-
}
|
|
69
|
-
async function mineBlock(provider) {
|
|
70
|
-
const bin = getBin(provider);
|
|
71
|
-
await executeJson({
|
|
72
|
-
contractAddress: UTIL_CONTRACT_ID,
|
|
73
|
-
functionName: "mine-block",
|
|
74
|
-
args: [],
|
|
75
|
-
provider: bin,
|
|
76
|
-
senderAddress: "ST000000000000000000002AMW42H"
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
async function mineBlocks(_blocks, provider) {
|
|
80
|
-
const blocks = intToBigInt(_blocks);
|
|
81
|
-
for (let index = 0; index < blocks; index++) {
|
|
82
|
-
await mineBlock(provider);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
async function getStxBalance(provider, account) {
|
|
86
|
-
const bin = getBin(provider);
|
|
87
|
-
const { output_serialized } = await evalJson({
|
|
88
|
-
contractAddress: UTIL_CONTRACT_ID,
|
|
89
|
-
functionName: "get-stx-balance",
|
|
90
|
-
args: [`'${account}`],
|
|
91
|
-
provider: bin
|
|
92
|
-
});
|
|
93
|
-
const outputCV = hexToCV(output_serialized);
|
|
94
|
-
const balance = cvToValue(outputCV);
|
|
95
|
-
return balance;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// src/utils/coverage.ts
|
|
99
|
-
import { mkdir, readdir, unlink } from "fs/promises";
|
|
100
|
-
import { join as join2, resolve } from "path";
|
|
101
|
-
async function setupCoverage(dir) {
|
|
102
|
-
const dirName = resolve(process.cwd(), "coverage");
|
|
103
|
-
try {
|
|
104
|
-
await mkdir(dirName);
|
|
105
|
-
} catch (error) {
|
|
106
|
-
}
|
|
107
|
-
const files = await readdir(dirName);
|
|
108
|
-
const removals = files.map((file) => {
|
|
109
|
-
return unlink(join2(dirName, file));
|
|
110
|
-
});
|
|
111
|
-
await Promise.all(removals);
|
|
112
|
-
return dirName;
|
|
113
|
-
}
|
|
114
|
-
async function finishCoverage(provider, dir) {
|
|
115
|
-
const lcovFile = join2(dir, "clarigen.lcov");
|
|
116
|
-
await provider.runCommand(["make_lcov", dir, lcovFile]);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// src/utils/index.ts
|
|
120
|
-
function makeRandomAddress(version = StacksNetworkVersion.testnetP2PKH) {
|
|
121
|
-
const privateKey = makeRandomPrivKey();
|
|
122
|
-
const publicKey = getPublicKeyFromStacksPrivateKey(privateKey);
|
|
123
|
-
const address = publicKeyToStxAddress(publicKey.data, version);
|
|
124
|
-
return address;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// src/utils/pure.ts
|
|
128
|
-
import {
|
|
129
|
-
cvToString,
|
|
130
|
-
cvToValue as cvToValue2,
|
|
131
|
-
filterEvents,
|
|
132
|
-
CoreNodeEventType,
|
|
133
|
-
ok,
|
|
134
|
-
err
|
|
135
|
-
} from "@clarigen/core";
|
|
136
|
-
import {
|
|
137
|
-
evalRaw,
|
|
138
|
-
evalJson as evalJson2,
|
|
139
|
-
executeJson as executeJson2
|
|
140
|
-
} from "@clarigen/native-bin";
|
|
141
|
-
import {
|
|
142
|
-
hexToCV as hexToCV2,
|
|
143
|
-
responseErrorCV,
|
|
144
|
-
responseOkCV
|
|
145
|
-
} from "micro-stacks/clarity";
|
|
146
|
-
function getPrints(events) {
|
|
147
|
-
return filterEvents(events, CoreNodeEventType.ContractEvent).map((e) => {
|
|
148
|
-
const hex = e.contract_event.raw_value;
|
|
149
|
-
const cv = hexToCV2(hex);
|
|
150
|
-
return cvToValue2(cv);
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
function formatArguments(args) {
|
|
154
|
-
return args.map((arg) => cvToString(arg));
|
|
155
|
-
}
|
|
156
|
-
function getIdentifier(tx2) {
|
|
157
|
-
return `${tx2.contractAddress}.${tx2.contractName}`;
|
|
158
|
-
}
|
|
159
|
-
function getLogs(stderr) {
|
|
160
|
-
if (stderr === "")
|
|
161
|
-
return [];
|
|
162
|
-
return stderr.split("\n").map((line) => line.slice(62));
|
|
163
|
-
}
|
|
164
|
-
function makeEvalResult(result) {
|
|
165
|
-
const resultCV = hexToCV2(result.output_serialized);
|
|
166
|
-
const value = cvToValue2(resultCV, true);
|
|
167
|
-
return {
|
|
168
|
-
value,
|
|
169
|
-
clarityValue: resultCV,
|
|
170
|
-
logs: getLogs(result.stderr),
|
|
171
|
-
costs: result.costs
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
async function ro({
|
|
175
|
-
tx: tx2,
|
|
176
|
-
bin,
|
|
177
|
-
coverageFolder
|
|
178
|
-
}) {
|
|
179
|
-
const result = await evalJson2({
|
|
180
|
-
functionName: tx2.function.name,
|
|
181
|
-
args: formatArguments(tx2.functionArgs),
|
|
182
|
-
contractAddress: getIdentifier(tx2),
|
|
183
|
-
provider: bin,
|
|
184
|
-
coverageFolder
|
|
185
|
-
});
|
|
186
|
-
return makeEvalResult(result);
|
|
187
|
-
}
|
|
188
|
-
async function evalCode({
|
|
189
|
-
contractAddress,
|
|
190
|
-
code,
|
|
191
|
-
bin,
|
|
192
|
-
coverageFolder
|
|
193
|
-
}) {
|
|
194
|
-
const result = await evalRaw({
|
|
195
|
-
contractAddress,
|
|
196
|
-
code,
|
|
197
|
-
provider: bin,
|
|
198
|
-
coverageFolder
|
|
199
|
-
});
|
|
200
|
-
return makeEvalResult(result);
|
|
201
|
-
}
|
|
202
|
-
async function tx({
|
|
203
|
-
tx: tx2,
|
|
204
|
-
senderAddress,
|
|
205
|
-
bin,
|
|
206
|
-
coverageFolder
|
|
207
|
-
}) {
|
|
208
|
-
const result = await executeJson2({
|
|
209
|
-
contractAddress: getIdentifier(tx2),
|
|
210
|
-
senderAddress,
|
|
211
|
-
provider: bin,
|
|
212
|
-
functionName: tx2.function.name,
|
|
213
|
-
args: formatArguments(tx2.functionArgs),
|
|
214
|
-
coverageFolder
|
|
215
|
-
});
|
|
216
|
-
const resultCV = hexToCV2(result.output_serialized);
|
|
217
|
-
const value = cvToValue2(resultCV);
|
|
218
|
-
const resp = result.success ? ok(value) : err(value);
|
|
219
|
-
const baseReturn = {
|
|
220
|
-
logs: getLogs(result.stderr),
|
|
221
|
-
costs: result.costs,
|
|
222
|
-
value: resp
|
|
223
|
-
};
|
|
224
|
-
if (result.success) {
|
|
225
|
-
return __spreadProps(__spreadValues({}, baseReturn), {
|
|
226
|
-
isOk: true,
|
|
227
|
-
response: responseOkCV(resultCV),
|
|
228
|
-
assets: result.assets,
|
|
229
|
-
events: result.events,
|
|
230
|
-
prints: getPrints(result.events)
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
return __spreadProps(__spreadValues({}, baseReturn), {
|
|
234
|
-
isOk: false,
|
|
235
|
-
response: responseErrorCV(resultCV)
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
async function mapGet({
|
|
239
|
-
map,
|
|
240
|
-
bin
|
|
241
|
-
}) {
|
|
242
|
-
const code = `(map-get? ${map.map.name} ${cvToString(map.key)})`;
|
|
243
|
-
const result = await evalCode({
|
|
244
|
-
contractAddress: getIdentifier(map),
|
|
245
|
-
code,
|
|
246
|
-
bin
|
|
247
|
-
});
|
|
248
|
-
return result.value;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// src/index.ts
|
|
252
|
-
import { resolve as resolve2 } from "path";
|
|
253
|
-
|
|
254
|
-
// src/utils/test-factory.ts
|
|
255
|
-
import {
|
|
256
|
-
projectFactory
|
|
257
|
-
} from "@clarigen/core";
|
|
258
|
-
function testFactory(project) {
|
|
259
|
-
return projectFactory(project, "simnet");
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// src/index.ts
|
|
263
|
-
import { Allocation, createClarityBin as createClarityBin2, executeJson as executeJson3, evalJson as evalJson3 } from "@clarigen/native-bin";
|
|
264
|
-
var TestProvider = class {
|
|
265
|
-
constructor(clarityBin) {
|
|
266
|
-
this.clarityBin = clarityBin;
|
|
267
|
-
}
|
|
268
|
-
static async fromContracts(contracts, options = {}) {
|
|
269
|
-
const clarityBin = options.clarityBin || await createClarityBin({
|
|
270
|
-
allocations: options.accounts
|
|
271
|
-
});
|
|
272
|
-
const instances = {};
|
|
273
|
-
let coverageFolder = options.coverageFolder;
|
|
274
|
-
if (process.env.CLARIGEN_COVERAGE) {
|
|
275
|
-
coverageFolder = resolve2(process.cwd(), "coverage");
|
|
276
|
-
}
|
|
277
|
-
await deployUtilContract(clarityBin);
|
|
278
|
-
for (const k in contracts) {
|
|
279
|
-
if (Object.prototype.hasOwnProperty.call(contracts, k)) {
|
|
280
|
-
const contract = contracts[k];
|
|
281
|
-
const identifier = getContractIdentifier(contract);
|
|
282
|
-
await deployContract2({
|
|
283
|
-
contractIdentifier: identifier,
|
|
284
|
-
contractFilePath: contract.contractFile,
|
|
285
|
-
provider: clarityBin,
|
|
286
|
-
coverageFolder
|
|
287
|
-
});
|
|
288
|
-
const instance = contract.contract(contract.address, contract.name);
|
|
289
|
-
instances[k] = {
|
|
290
|
-
identifier: getContractIdentifier(contract),
|
|
291
|
-
contract: instance
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
const provider = new this(clarityBin);
|
|
296
|
-
provider.coverageFolder = coverageFolder;
|
|
297
|
-
return {
|
|
298
|
-
deployed: instances,
|
|
299
|
-
provider
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
static async fromProject(simnet, options = {}) {
|
|
303
|
-
const allocations = Object.fromEntries(Object.entries(simnet.accounts).map(([name, account]) => {
|
|
304
|
-
return [name, __spreadProps(__spreadValues({}, account), { balance: BigInt(account.balance) })];
|
|
305
|
-
}));
|
|
306
|
-
const clarityBin = options.clarityBin || await createClarityBin({
|
|
307
|
-
allocations
|
|
308
|
-
});
|
|
309
|
-
let coverageFolder = options.coverageFolder;
|
|
310
|
-
if (process.env.CLARIGEN_COVERAGE) {
|
|
311
|
-
coverageFolder = resolve2(process.cwd(), "coverage");
|
|
312
|
-
}
|
|
313
|
-
await deployUtilContract(clarityBin);
|
|
314
|
-
for (const contract of simnet.deployment) {
|
|
315
|
-
let contractFilePath = contract.file;
|
|
316
|
-
if (options.clarinetPath) {
|
|
317
|
-
contractFilePath = resolve2(process.cwd(), options.clarinetPath, contractFilePath);
|
|
318
|
-
}
|
|
319
|
-
await deployContract2({
|
|
320
|
-
contractIdentifier: contract.identifier,
|
|
321
|
-
contractFilePath,
|
|
322
|
-
provider: clarityBin,
|
|
323
|
-
coverageFolder
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
const provider = new this(clarityBin);
|
|
327
|
-
provider.coverageFolder = coverageFolder;
|
|
328
|
-
return provider;
|
|
329
|
-
}
|
|
330
|
-
static async fromFactory(contracts, options = {}) {
|
|
331
|
-
const clarityBin = options.clarityBin || await createClarityBin({
|
|
332
|
-
allocations: options.accounts
|
|
333
|
-
});
|
|
334
|
-
let coverageFolder = options.coverageFolder;
|
|
335
|
-
if (process.env.CLARIGEN_COVERAGE) {
|
|
336
|
-
coverageFolder = resolve2(process.cwd(), "coverage");
|
|
337
|
-
}
|
|
338
|
-
await deployUtilContract(clarityBin);
|
|
339
|
-
for (const k in contracts) {
|
|
340
|
-
if (Object.prototype.hasOwnProperty.call(contracts, k)) {
|
|
341
|
-
const contract = contracts[k];
|
|
342
|
-
let contractFilePath = contract.contractFile;
|
|
343
|
-
if (options.clarinetPath) {
|
|
344
|
-
contractFilePath = resolve2(process.cwd(), options.clarinetPath, contractFilePath);
|
|
345
|
-
}
|
|
346
|
-
if (typeof contractFilePath === "undefined") {
|
|
347
|
-
throw new Error("Cannot setup @clarigen/test - missing contract file.");
|
|
348
|
-
}
|
|
349
|
-
await deployContract2({
|
|
350
|
-
contractIdentifier: contract.identifier,
|
|
351
|
-
contractFilePath,
|
|
352
|
-
provider: clarityBin,
|
|
353
|
-
coverageFolder
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
const provider = new this(clarityBin);
|
|
358
|
-
provider.coverageFolder = coverageFolder;
|
|
359
|
-
return provider;
|
|
360
|
-
}
|
|
361
|
-
ro(tx2) {
|
|
362
|
-
return ro({ tx: tx2, bin: this.clarityBin, coverageFolder: this.coverageFolder });
|
|
363
|
-
}
|
|
364
|
-
async rov(tx2) {
|
|
365
|
-
const result = await this.ro(tx2);
|
|
366
|
-
return result.value;
|
|
367
|
-
}
|
|
368
|
-
async roOk(tx2) {
|
|
369
|
-
const result = await this.ro(tx2);
|
|
370
|
-
const value = expectOk(result.value);
|
|
371
|
-
return __spreadProps(__spreadValues({}, result), {
|
|
372
|
-
value
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
async roErr(tx2) {
|
|
376
|
-
const result = await this.ro(tx2);
|
|
377
|
-
const value = expectErr(result.value);
|
|
378
|
-
return __spreadProps(__spreadValues({}, result), {
|
|
379
|
-
value
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
async rovOk(tx2) {
|
|
383
|
-
return (await this.roOk(tx2)).value;
|
|
384
|
-
}
|
|
385
|
-
async rovErr(tx2) {
|
|
386
|
-
return (await this.roErr(tx2)).value;
|
|
387
|
-
}
|
|
388
|
-
tx(tx2, senderAddress) {
|
|
389
|
-
return tx({
|
|
390
|
-
tx: tx2,
|
|
391
|
-
senderAddress,
|
|
392
|
-
bin: this.clarityBin,
|
|
393
|
-
coverageFolder: this.coverageFolder
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
async txOk(tx2, senderAddress) {
|
|
397
|
-
const result = await this.tx(tx2, senderAddress);
|
|
398
|
-
const value = expectOk(result.value);
|
|
399
|
-
if (!result.isOk)
|
|
400
|
-
throw new Error(`Expected OK, received error: ${String(result.value)}`);
|
|
401
|
-
return __spreadProps(__spreadValues({}, result), {
|
|
402
|
-
value
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
async txErr(tx2, senderAddress) {
|
|
406
|
-
const result = await this.tx(tx2, senderAddress);
|
|
407
|
-
const value = expectErr(result.value);
|
|
408
|
-
if (result.isOk)
|
|
409
|
-
throw new Error(`Expected Err, received ok: ${String(result.value)}`);
|
|
410
|
-
return __spreadProps(__spreadValues({}, result), {
|
|
411
|
-
value
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
evalCode(code, contractAddress = UTIL_CONTRACT_ID) {
|
|
415
|
-
return evalCode({
|
|
416
|
-
contractAddress,
|
|
417
|
-
code,
|
|
418
|
-
bin: this.clarityBin,
|
|
419
|
-
coverageFolder: this.coverageFolder
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
async eval(code, contractAddress = UTIL_CONTRACT_ID) {
|
|
423
|
-
const result = await this.evalCode(code, contractAddress);
|
|
424
|
-
return result.value;
|
|
425
|
-
}
|
|
426
|
-
mapGet(map) {
|
|
427
|
-
return mapGet({ map, bin: this.clarityBin });
|
|
428
|
-
}
|
|
429
|
-
};
|
|
430
|
-
export {
|
|
431
|
-
Allocation,
|
|
432
|
-
TestProvider,
|
|
433
|
-
createClarityBin2 as createClarityBin,
|
|
434
|
-
evalJson3 as evalJson,
|
|
435
|
-
executeJson3 as executeJson,
|
|
436
|
-
finishCoverage,
|
|
437
|
-
getBlockHeight,
|
|
438
|
-
getStxBalance,
|
|
439
|
-
makeRandomAddress,
|
|
440
|
-
mineBlocks,
|
|
441
|
-
setupCoverage,
|
|
442
|
-
testFactory
|
|
443
|
-
};
|
|
1
|
+
var d=Object.defineProperty,R=Object.defineProperties;var m=Object.getOwnPropertyDescriptors;var u=Object.getOwnPropertySymbols;var C=Object.prototype.hasOwnProperty,f=Object.prototype.propertyIsEnumerable;var p=(n,r,e)=>r in n?d(n,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[r]=e,i=(n,r)=>{for(var e in r||(r={}))C.call(r,e)&&p(n,e,r[e]);if(u)for(var e of u(r))f.call(r,e)&&p(n,e,r[e]);return n},l=(n,r)=>R(n,m(r));import{cvToValue as y}from"@clarigen/core";import{deserializeCV as A,serializeCV as T}from"@stacks/transactions";import{serializeCV as g,deserializeCV as v}from"micro-stacks/clarity";function s(n){return A(g(n))}function V(n){return v(T(n))}function c(n,r){let e=y(V(n),!0);if(typeof r<"u"&&"isOk"in e){let a=e,t=a.value;if(r&&!a.isOk)throw new Error(`Tx result failed. Expected OK, received ERR ${t}.`);if(r===!1&&a.isOk)throw new Error(`Tx result failed. Expected ERR, received OK ${t}.`);return t}return e}function k(n,r){let e=n.functionArgs.map(s),a=`${n.contractAddress}.${n.contractName}`,t=simnet.callPublicFn(a,n.function.name,e,r),o=c(t.result,!0);return l(i({},t),{value:o})}function $(n,r){let e=n.functionArgs.map(s),a=`${n.contractAddress}.${n.contractName}`,t=simnet.callPublicFn(a,n.function.name,e,r),o=c(t.result,!1);return l(i({},t),{value:o})}function w(n,r){let e=n.functionArgs.map(s),a=`${n.contractAddress}.${n.contractName}`,t=simnet.callPublicFn(a,n.function.name,e,r),o=c(t.result);return l(i({},t),{value:o})}function E(n,r){let e=n.functionArgs.map(s),a=`${n.contractAddress}.${n.contractName}`,t=simnet.callReadOnlyFn(a,n.function.name,e,r);return c(t.result)}function O(n,r){let e=n.functionArgs.map(s),a=`${n.contractAddress}.${n.contractName}`,t=simnet.callReadOnlyFn(a,n.function.name,e,r);return c(t.result,!0)}function S(n,r){let e=n.functionArgs.map(s),a=`${n.contractAddress}.${n.contractName}`,t=simnet.callReadOnlyFn(a,n.function.name,e,r);return c(t.result,!1)}var j={txOk:k,txErr:$,tx:w,ro:E,roOk:O,roErr:S};export{j as chain,E as ro,S as roErr,O as roOk,w as tx,$ as txErr,k as txOk};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/index.ts"],"sourcesContent":["import { Response, cvToValue } from '@clarigen/core';\nimport {\n ClarityValue as HiroClarityValue,\n deserializeCV as deserializeCVHiro,\n serializeCV as serializeCVHiro,\n StandardPrincipalCV as HiroPrincipalCV,\n} from '@stacks/transactions';\nimport {\n ClarityValue as MSClarityValue,\n StandardPrincipalCV as MSPrincipalCV,\n serializeCV as serializeCVMS,\n deserializeCV as deserializeCVMS,\n ClarityAbiFunction,\n} from 'micro-stacks/clarity';\n\nexport function cvConvertMS(value: MSClarityValue): HiroClarityValue {\n return deserializeCVHiro(serializeCVMS(value));\n}\n\nexport function cvConvertHiro(value: HiroClarityValue): MSClarityValue {\n return deserializeCVMS(serializeCVHiro(value));\n}\n\nexport function validateResponse<T>(result: HiroClarityValue, expectOk?: boolean): T {\n const value = cvToValue(cvConvertHiro(result), true);\n if (typeof expectOk !== 'undefined' && 'isOk' in value) {\n const response = value as Response<unknown, unknown>;\n const inner = response.value;\n if (expectOk && !response.isOk) {\n throw new Error(`Tx result failed. Expected OK, received ERR ${inner}.`);\n }\n if (expectOk === false && response.isOk) {\n throw new Error(`Tx result failed. Expected ERR, received OK ${inner}.`);\n }\n return inner as T;\n }\n return value;\n}\n","import { ContractCallTyped, ErrType, OkType, UnknownArgs } from '@clarigen/core';\nimport { Simnet, ParsedTransactionResult } from '@hirosystems/clarinet-sdk';\nimport { cvConvertMS, validateResponse } from './utils';\n\ndeclare global {\n var simnet: Simnet;\n}\n\nexport type TransactionResult<R> = ParsedTransactionResult & {\n value: R;\n};\n\nexport function txOk<A extends UnknownArgs, R>(\n tx: ContractCallTyped<A, R>,\n sender: string\n): TransactionResult<OkType<R>> {\n const args = tx.functionArgs.map(cvConvertMS);\n const contractId = `${tx.contractAddress}.${tx.contractName}`;\n const receipt = simnet.callPublicFn(contractId, tx.function.name, args, sender);\n const value = validateResponse<OkType<R>>(receipt.result, true);\n\n return {\n ...receipt,\n value,\n };\n}\n\nexport function txErr<A extends UnknownArgs, R>(\n tx: ContractCallTyped<A, R>,\n sender: string\n): TransactionResult<ErrType<R>> {\n const args = tx.functionArgs.map(cvConvertMS);\n const contractId = `${tx.contractAddress}.${tx.contractName}`;\n const receipt = simnet.callPublicFn(contractId, tx.function.name, args, sender);\n const value = validateResponse<ErrType<R>>(receipt.result, false);\n\n return {\n ...receipt,\n value,\n };\n}\n\nexport function tx<A extends UnknownArgs, R>(\n tx: ContractCallTyped<A, R>,\n sender: string\n): TransactionResult<R> {\n const args = tx.functionArgs.map(cvConvertMS);\n const contractId = `${tx.contractAddress}.${tx.contractName}`;\n const receipt = simnet.callPublicFn(contractId, tx.function.name, args, sender);\n const value = validateResponse<R>(receipt.result);\n\n return {\n ...receipt,\n value,\n };\n}\n\nexport function ro<A extends UnknownArgs, R>(tx: ContractCallTyped<A, R>, sender: string): R {\n const args = tx.functionArgs.map(cvConvertMS);\n const contractId = `${tx.contractAddress}.${tx.contractName}`;\n const receipt = simnet.callReadOnlyFn(contractId, tx.function.name, args, sender);\n const value = validateResponse<R>(receipt.result);\n\n return value;\n}\n\nexport function roOk<A extends UnknownArgs, R>(\n tx: ContractCallTyped<A, R>,\n sender: string\n): OkType<R> {\n const args = tx.functionArgs.map(cvConvertMS);\n const contractId = `${tx.contractAddress}.${tx.contractName}`;\n const receipt = simnet.callReadOnlyFn(contractId, tx.function.name, args, sender);\n const value = validateResponse<OkType<R>>(receipt.result, true);\n\n return value;\n}\n\nexport function roErr<A extends UnknownArgs, R>(\n tx: ContractCallTyped<A, R>,\n sender: string\n): ErrType<R> {\n const args = tx.functionArgs.map(cvConvertMS);\n const contractId = `${tx.contractAddress}.${tx.contractName}`;\n const receipt = simnet.callReadOnlyFn(contractId, tx.function.name, args, sender);\n const value = validateResponse<ErrType<R>>(receipt.result, false);\n\n return value;\n}\n\n// Helper export for previous Deno-based tests\nexport const chain = {\n txOk,\n txErr,\n tx,\n ro,\n roOk,\n roErr,\n};\n"],"mappings":"6aAAA,2CACA,sEAMA,sEAQO,WAAqB,EAAyC,CACnE,MAAO,GAAkB,EAAc,CAAK,CAAC,CAC/C,CAEO,WAAuB,EAAyC,CACrE,MAAO,GAAgB,EAAgB,CAAK,CAAC,CAC/C,CAEO,WAA6B,EAA0B,EAAuB,CACnF,GAAM,GAAQ,EAAU,EAAc,CAAM,EAAG,EAAI,EACnD,GAAI,MAAO,GAAa,KAAe,QAAU,GAAO,CACtD,GAAM,GAAW,EACX,EAAQ,EAAS,MACvB,GAAI,GAAY,CAAC,EAAS,KACxB,KAAM,IAAI,OAAM,+CAA+C,IAAQ,EAEzE,GAAI,IAAa,IAAS,EAAS,KACjC,KAAM,IAAI,OAAM,+CAA+C,IAAQ,EAEzE,MAAO,EACT,CACA,MAAO,EACT,CCzBO,WACL,EACA,EAC8B,CAC9B,GAAM,GAAO,EAAG,aAAa,IAAI,CAAW,EACtC,EAAa,GAAG,EAAG,mBAAmB,EAAG,eACzC,EAAU,OAAO,aAAa,EAAY,EAAG,SAAS,KAAM,EAAM,CAAM,EACxE,EAAQ,EAA4B,EAAQ,OAAQ,EAAI,EAE9D,MAAO,QACF,GADE,CAEL,OACF,EACF,CAEO,WACL,EACA,EAC+B,CAC/B,GAAM,GAAO,EAAG,aAAa,IAAI,CAAW,EACtC,EAAa,GAAG,EAAG,mBAAmB,EAAG,eACzC,EAAU,OAAO,aAAa,EAAY,EAAG,SAAS,KAAM,EAAM,CAAM,EACxE,EAAQ,EAA6B,EAAQ,OAAQ,EAAK,EAEhE,MAAO,QACF,GADE,CAEL,OACF,EACF,CAEO,WACL,EACA,EACsB,CACtB,GAAM,GAAO,EAAG,aAAa,IAAI,CAAW,EACtC,EAAa,GAAG,EAAG,mBAAmB,EAAG,eACzC,EAAU,OAAO,aAAa,EAAY,EAAG,SAAS,KAAM,EAAM,CAAM,EACxE,EAAQ,EAAoB,EAAQ,MAAM,EAEhD,MAAO,QACF,GADE,CAEL,OACF,EACF,CAEO,WAAsC,EAA6B,EAAmB,CAC3F,GAAM,GAAO,EAAG,aAAa,IAAI,CAAW,EACtC,EAAa,GAAG,EAAG,mBAAmB,EAAG,eACzC,EAAU,OAAO,eAAe,EAAY,EAAG,SAAS,KAAM,EAAM,CAAM,EAGhF,MAFc,GAAoB,EAAQ,MAAM,CAGlD,CAEO,WACL,EACA,EACW,CACX,GAAM,GAAO,EAAG,aAAa,IAAI,CAAW,EACtC,EAAa,GAAG,EAAG,mBAAmB,EAAG,eACzC,EAAU,OAAO,eAAe,EAAY,EAAG,SAAS,KAAM,EAAM,CAAM,EAGhF,MAFc,GAA4B,EAAQ,OAAQ,EAAI,CAGhE,CAEO,WACL,EACA,EACY,CACZ,GAAM,GAAO,EAAG,aAAa,IAAI,CAAW,EACtC,EAAa,GAAG,EAAG,mBAAmB,EAAG,eACzC,EAAU,OAAO,eAAe,EAAY,EAAG,SAAS,KAAM,EAAM,CAAM,EAGhF,MAFc,GAA6B,EAAQ,OAAQ,EAAK,CAGlE,CAGO,GAAM,GAAQ,CACnB,OACA,QACA,KACA,KACA,OACA,OACF","names":[]}
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.0.
|
|
2
|
+
"version": "1.0.16-alpha.0",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"types": "./dist/index.d.ts",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
7
7
|
"import": "./dist/index.mjs",
|
|
8
8
|
"files": [
|
|
9
|
-
"dist"
|
|
10
|
-
"contracts"
|
|
9
|
+
"dist"
|
|
11
10
|
],
|
|
12
11
|
"engines": {
|
|
13
12
|
"node": ">=10"
|
|
@@ -16,24 +15,26 @@
|
|
|
16
15
|
"name": "@clarigen/test",
|
|
17
16
|
"author": "Hank Stoever",
|
|
18
17
|
"devDependencies": {
|
|
19
|
-
"
|
|
18
|
+
"@types/node": "20.10.4",
|
|
19
|
+
"vitest": "1.0.4",
|
|
20
|
+
"demo-project": "1.0.16-alpha.0"
|
|
20
21
|
},
|
|
21
22
|
"dependencies": {
|
|
22
|
-
"
|
|
23
|
-
"@
|
|
24
|
-
"
|
|
23
|
+
"micro-stacks": "^1.1.4",
|
|
24
|
+
"@stacks/transactions": "6.10.0",
|
|
25
|
+
"@hirosystems/clarinet-sdk": "1.2.0",
|
|
26
|
+
"@hirosystems/clarinet-sdk-wasm": "1.2.0",
|
|
27
|
+
"@clarigen/core": "1.0.16-alpha.0"
|
|
25
28
|
},
|
|
26
29
|
"publishConfig": {
|
|
27
30
|
"access": "public"
|
|
28
31
|
},
|
|
29
32
|
"scripts": {
|
|
30
|
-
"start": "tsup
|
|
31
|
-
"dev": "tsup
|
|
32
|
-
"build": "shx rm -rf
|
|
33
|
-
"test": "
|
|
34
|
-
"lint": "eslint \"src/**/*.{ts,tsx}\" && prettier
|
|
35
|
-
"typecheck": "tsc --noEmit"
|
|
36
|
-
"build-test-types": "sh build-types.sh",
|
|
37
|
-
"publish:dev": "pnpm build && yalc publish --push"
|
|
33
|
+
"start": "tsup --watch",
|
|
34
|
+
"dev": "tsup --watch",
|
|
35
|
+
"build": "shx rm -rf dist && tsup",
|
|
36
|
+
"test": "jest --passWithNoTests",
|
|
37
|
+
"lint": "eslint \"src/**/*.{ts,tsx}\" && prettier --check \"./**/*.{ts,js}\"",
|
|
38
|
+
"typecheck": "tsc --noEmit"
|
|
38
39
|
}
|
|
39
40
|
}
|
package/README.md
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
# `@clarigen/test`
|
|
2
|
-
|
|
3
|
-
`@clarigen/test` is a tool for running unit tests on Clarity smart contracts in a TypeScript environment.
|
|
4
|
-
|
|
5
|
-
For project setup instructions, check out the [Clarigen setup guide](https://github.com/hstove/clarigen#setup-guide).
|
|
6
|
-
|
|
7
|
-
This tool is agnostic to whichever testing framework you like to use. You're free to use Jest, Mocha, or whatever node.js testing library you enjoy.
|
|
8
|
-
|
|
9
|
-
Under the hood, this package uses the [`@clarigen/native-bin`](https://github.com/obylabs/clarigen/tree/main/packages/native-bin) package. At a lower level, the `clarity-cli` binary (from [`stacks-blockchain`](https://github.com/blockstack/stacks-blockchain)) is used to simulate a Stacks blockchain environment, especially for tests.
|
|
10
|
-
|
|
11
|
-
<!-- TOC depthfrom:2 -->
|
|
12
|
-
|
|
13
|
-
- [Guide](#guide)
|
|
14
|
-
- [Importing Clarigen packages and modules](#importing-clarigen-packages-and-modules)
|
|
15
|
-
- [Deploying contracts](#deploying-contracts)
|
|
16
|
-
- [Interacting with contracts](#interacting-with-contracts)
|
|
17
|
-
- [Read-only methods](#read-only-methods)
|
|
18
|
-
- [Public functions](#public-functions)
|
|
19
|
-
|
|
20
|
-
<!-- /TOC -->
|
|
21
|
-
|
|
22
|
-
## Guide
|
|
23
|
-
|
|
24
|
-
All code samples are taken from the [Clarigen counter example](https://github.com/hstove/clarigen-counter-example) repository.
|
|
25
|
-
|
|
26
|
-
You can also see some real-world usage to better understand how to use it:
|
|
27
|
-
|
|
28
|
-
- [CounterCoin unit tests](https://github.com/hstove/clarigen-counter-example/blob/main/test/counter.test.ts)
|
|
29
|
-
- [Fungible token unit tests](https://github.com/hstove/stacks-fungible-token/blob/main/test/token.test.ts)
|
|
30
|
-
|
|
31
|
-
### Importing Clarigen packages and modules
|
|
32
|
-
|
|
33
|
-
When writing tests, you'll need to import each contract that you wish to deploy and use. Clarigen automatically generates and exports a few variables for each of your Clarity contracts. The one's you'll typically use are:
|
|
34
|
-
|
|
35
|
-
- `${contractName}Info` - An object that includes the contract file path and deployer address
|
|
36
|
-
- `${contractName}Contract` - a Typescript interface that represents the methods available on your contract
|
|
37
|
-
|
|
38
|
-
You'll also want to import `TestProvider` from `@clarigen/test`. You might also end up importing a few helper methods, which are explained later.
|
|
39
|
-
|
|
40
|
-
```ts
|
|
41
|
-
import { TestProvider, txErr, txOk } from '@clarigen/test';
|
|
42
|
-
|
|
43
|
-
// Make sure you import from the `outputDir` specified in clarigen.config.json
|
|
44
|
-
import { CounterContract, CounterCoinContract, contracts } from '../src/clarigen';
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Deploying contracts
|
|
48
|
-
|
|
49
|
-
You'll need to deploy contracts before running your tests. Typically, this is done using the `beforeAll` hook in Jest, or similar in your framework.
|
|
50
|
-
|
|
51
|
-
`TestProvider` includes a `fromContracts` method that accepts an object of your contracts.
|
|
52
|
-
|
|
53
|
-
**Important**: the order in which you specify contracts is important. Often times, one contract will depend on a different contract. Contracts are deployed in the order of which they are specified.
|
|
54
|
-
|
|
55
|
-
```ts
|
|
56
|
-
// `contracts` is imported from '../src/clarigen'
|
|
57
|
-
const deployed = await TestProvider.fromContracts(contracts);
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
The result of `TestProvider.fromContracts` is an object that includes all of your contract interfaces. This result is what you'll use to actually call contract methods. The keys of this object are the camel-cased file names of your contracts. So, `my-token.clar` will be `myToken`.
|
|
61
|
-
|
|
62
|
-
```ts
|
|
63
|
-
const { counter } = deployed;
|
|
64
|
-
|
|
65
|
-
// calling contract functions:
|
|
66
|
-
await counter.getCounter();
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
If you're using Clarinet with Clarigen, then you can automatically import and include your default account balances.
|
|
70
|
-
|
|
71
|
-
```ts
|
|
72
|
-
import { accounts, contracts } from '../src/clarigen';
|
|
73
|
-
|
|
74
|
-
await TestProvider.fromContracts(contracts, accounts);
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Interacting with contracts
|
|
78
|
-
|
|
79
|
-
There are two ways of interacting with a contract: read-only methods, and public methods.
|
|
80
|
-
|
|
81
|
-
#### Read-only methods
|
|
82
|
-
|
|
83
|
-
Read-only methods do not change state, so they can be called without making a transaction.
|
|
84
|
-
|
|
85
|
-
In the [counter example](https://github.com/hstove/clarigen-counter-example), there is the read-only method `get-counter`:
|
|
86
|
-
|
|
87
|
-
```clar
|
|
88
|
-
(define-data-var counter int 0)
|
|
89
|
-
|
|
90
|
-
(define-read-only (get-counter)
|
|
91
|
-
(var-get counter))
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Clarigen will automatically expose a JS-friendly method for calling this function and getting the result. Clarigen converts all method names from kebab-case (`get-counter`) to camelCase (`getCounter`).
|
|
95
|
-
|
|
96
|
-
```ts
|
|
97
|
-
const value = await counter.getCounter();
|
|
98
|
-
console.log(value); // prints "0n"
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
For most Clarity types, Clarigen converts values into JS-friendly values, and all methods are strongly typed to TypeScript types. In the above example, `getCounter` returns a `number`.
|
|
102
|
-
|
|
103
|
-
Sometimes, read-only methods return a `response`. A `response` is a value that can be either "ok" or an error. The type returned for `ok` and `err` are different. Clarigen returns a [neverthrow](https://github.com/supermacro/neverthrow) type for read-only functions that return a `response`. Refer to the neverthrow docs for full usage.
|
|
104
|
-
|
|
105
|
-
For an example, here is a read-only function that returns a `response`:
|
|
106
|
-
|
|
107
|
-
```clar
|
|
108
|
-
(define-read-only (check-even (x uint))
|
|
109
|
-
(if (is-eq (mod x 2) 0)
|
|
110
|
-
(ok x)
|
|
111
|
-
(err false))
|
|
112
|
-
)
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
If the response is `ok`, it returns a number, otherwise it returns a boolean for `err`. Here's what that looks like with Clarigen:
|
|
116
|
-
|
|
117
|
-
```ts
|
|
118
|
-
const response = await myContract.checkEven(3);
|
|
119
|
-
if (response.isOk) {
|
|
120
|
-
console.log('Ok', response.value); // prints "Ok 3"
|
|
121
|
-
} else {
|
|
122
|
-
console.log('Err', response.value); // prints "Err false"
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
#### Public functions
|
|
127
|
-
|
|
128
|
-
Public functions are callable by anyone, and are invoked by making a contract-call transaction. In a test environment, we are simulating a full blockchain, but the behavior is the same.
|
|
129
|
-
|
|
130
|
-
`@clarigen/test` provides a few helper functions for submitting a transaction:
|
|
131
|
-
|
|
132
|
-
- `tx`: Submit a transaction and get a response (which can be either `ok` or `err`)
|
|
133
|
-
- `txOk`: Submit a transaction and throw an error if the result is not `ok`
|
|
134
|
-
- `txErr`: Submit a transaction and throw and error if the response is not `err`
|
|
135
|
-
|
|
136
|
-
The API for these helper methods is `tx(Transaction<Ok, Err>, sender: string)`. Here are some examples:
|
|
137
|
-
|
|
138
|
-
```ts
|
|
139
|
-
import { tx, txOk, txErr } from '@clarigen/test';
|
|
140
|
-
|
|
141
|
-
const sender = 'ST3J2GVMMM2R07ZFBJDWTYEYAR8FZH5WKDTFJ9AHA';
|
|
142
|
-
|
|
143
|
-
// Submit a tx. The type of `responseMaybe.value` is either `ok`, or `err`, so
|
|
144
|
-
// you must check `isOk` before writing type-safe code
|
|
145
|
-
const responseMaybe = await tx(counter.increment(), sender);
|
|
146
|
-
|
|
147
|
-
// `responseOk.value` is strictly typed, because the helper will throw if `isOk !== true`
|
|
148
|
-
const responseOk = await txOk(counter.increment(), sender);
|
|
149
|
-
|
|
150
|
-
// `responseErr.value` is strictly typed, because the helper will throw if `isOk !== false`
|
|
151
|
-
const responseErr = await txErr(counter.increment(), sender);
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
The return type of these methods are specified below. `tx` returns `TransactionResult<Ok, Err>`, `txOk` returns `TransactionResultOk`, and `txErr` returns `TransactionResultErr`.
|
|
155
|
-
|
|
156
|
-
```ts
|
|
157
|
-
export interface TransactionResultOk<Ok> {
|
|
158
|
-
value: Ok;
|
|
159
|
-
response: ResponseOk<Ok>;
|
|
160
|
-
isOk: true;
|
|
161
|
-
events: any[];
|
|
162
|
-
costs: {
|
|
163
|
-
runtime: number;
|
|
164
|
-
};
|
|
165
|
-
assets: ResultAssets;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export interface TransactionResultErr<Err> {
|
|
169
|
-
value: Err;
|
|
170
|
-
response: ResponseErr<Err>;
|
|
171
|
-
costs: {
|
|
172
|
-
runtime: number;
|
|
173
|
-
};
|
|
174
|
-
isOk: false;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export type TransactionResult<Ok, Err> = TransactionResultOk<Ok> | TransactionResultErr<Err>;
|
|
178
|
-
```
|