Skip to content

Commit 91701a8

Browse files
committed
Improve testing-suite
1 parent f8e82bb commit 91701a8

16 files changed

Lines changed: 314 additions & 93 deletions

examples/testing-suite/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
**/dist/
2+
**/node_modules/

examples/testing-suite/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# CashScript Testing Suite
2+
3+
This is an example project to demonstrate how to write and compile CashScript contracts and test them using the CashScript SDK and Vitest.
4+
5+
## Writing a CashScript contract
6+
7+
We have included two simple example contracts in the `contracts/` directory that can be used as a starting point to write your own contracts. The contracts demonstrate logs, require statements and transaction signatures.
8+
9+
## Compiling the contracts
10+
11+
We have included a task to compile the contracts in the `tasks/` directory called `compile.ts`. This task will compile all the contracts in the `contracts/` directory and save the artifacts in the `artifacts/` directory. This includes both the JSON and TypeScript artifacts. It is recommended to use the TypeScript artifacts for proper type-safety.
12+
13+
You can run the task with `yarn compile`.
14+
15+
## Running the tests
16+
17+
We have included test files in the `test/` directory, which test the expected functionality of the contracts. For key management, we have included a utility file in the `utils/` directory which exports testing keys for Alice and Bob.
18+
19+
You can run the tests with `yarn test`.
20+
21+
## Next steps
22+
23+
Once you're getting comfortable writing, compiling and testing CashScript contracts, you can copy the `testing-suite` directory into your own project to use as a starting point. From there you can start writing more complex contracts and integrate them into full applications.
24+
25+
We recommend checking out the [CashScript SDK documentation](https://cashscript.org/docs/sdk/) for more information on how to use the CashScript SDK, and the specific section on the [testing setup](https://cashscript.org/docs/sdk/testing-setup) for more information on how to test your contracts.

examples/testing-suite/artifacts/example.artifact.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ export default {
1313
},
1414
],
1515
bytecode: 'OP_1 OP_NUMEQUAL',
16-
source: 'contract Example() {\n function test(int value) {\n console.log(value, \'test\');\n require(value == 1, \'Wrong value passed\');\n }\n}\n',
16+
source: 'contract Example() {\n function test(int value) {\n console.log(value, "test");\n require(value == 1, "Wrong value passed");\n }\n}\n',
1717
debug: {
18-
bytecode: '007a519c',
19-
sourceMap: '4:12:4:17;;:21::22;:12:::1',
18+
bytecode: '519c',
19+
sourceMap: '4:21:4:22;:4::46:1',
2020
logs: [
2121
{
2222
ip: 0,
@@ -33,15 +33,15 @@ export default {
3333
],
3434
requires: [
3535
{
36-
ip: 4,
36+
ip: 2,
3737
line: 4,
3838
message: 'Wrong value passed',
3939
},
4040
],
4141
},
4242
compiler: {
4343
name: 'cashc',
44-
version: '0.11.0',
44+
version: '0.13.0-next.2',
4545
},
46-
updatedAt: '2025-04-11T09:08:09.750Z',
46+
updatedAt: '2026-01-13T10:40:29.996Z',
4747
} as const;

examples/testing-suite/artifacts/example.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
},
4242
"compiler": {
4343
"name": "cashc",
44-
"version": "0.13.0"
44+
"version": "0.13.0-next.2"
4545
},
46-
"updatedAt": "2025-12-09T10:19:09.338Z"
47-
}
46+
"updatedAt": "2026-01-13T10:40:29.996Z"
47+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
export default {
2+
contractName: 'TransferWithTimeout',
3+
constructorInputs: [
4+
{
5+
name: 'sender',
6+
type: 'pubkey',
7+
},
8+
{
9+
name: 'recipient',
10+
type: 'pubkey',
11+
},
12+
{
13+
name: 'timeout',
14+
type: 'int',
15+
},
16+
],
17+
abi: [
18+
{
19+
name: 'transfer',
20+
inputs: [
21+
{
22+
name: 'recipientSig',
23+
type: 'sig',
24+
},
25+
],
26+
},
27+
{
28+
name: 'timeout',
29+
inputs: [
30+
{
31+
name: 'senderSig',
32+
type: 'sig',
33+
},
34+
],
35+
},
36+
],
37+
bytecode: 'OP_3 OP_PICK OP_0 OP_NUMEQUAL OP_IF OP_4 OP_ROLL OP_ROT OP_CHECKSIG OP_NIP OP_NIP OP_NIP OP_ELSE OP_3 OP_ROLL OP_1 OP_NUMEQUALVERIFY OP_3 OP_ROLL OP_SWAP OP_CHECKSIGVERIFY OP_SWAP OP_CHECKLOCKTIMEVERIFY OP_2DROP OP_1 OP_ENDIF',
38+
source: 'pragma cashscript ^0.13.0;\n\ncontract TransferWithTimeout(\n pubkey sender,\n pubkey recipient,\n int timeout\n) {\n // Require recipient\'s signature to match\n function transfer(sig recipientSig) {\n require(checkSig(recipientSig, recipient));\n }\n\n // Require timeout time to be reached and sender\'s signature to match\n function timeout(sig senderSig) {\n require(checkSig(senderSig, sender));\n require(tx.time >= timeout);\n }\n}\n',
39+
debug: {
40+
bytecode: '5379009c63547a7bac77777767537a519d537a7cad7cb16d5168',
41+
sourceMap: '9:4:11:5;;;;;10:25:10:37;;:39::48;:8::51:1;9:4:11:5;;;;14::17::0;;;;15:25:15:34;;:36::42;:8::45:1;16:27:16:34:0;:8::36:1;14:4:17:5;;3:0:18:1',
42+
logs: [],
43+
requires: [
44+
{
45+
ip: 12,
46+
line: 10,
47+
},
48+
{
49+
ip: 23,
50+
line: 15,
51+
},
52+
{
53+
ip: 25,
54+
line: 16,
55+
},
56+
],
57+
},
58+
compiler: {
59+
name: 'cashc',
60+
version: '0.13.0-next.2',
61+
},
62+
updatedAt: '2026-01-13T10:40:30.007Z',
63+
} as const;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"contractName": "TransferWithTimeout",
3+
"constructorInputs": [
4+
{
5+
"name": "sender",
6+
"type": "pubkey"
7+
},
8+
{
9+
"name": "recipient",
10+
"type": "pubkey"
11+
},
12+
{
13+
"name": "timeout",
14+
"type": "int"
15+
}
16+
],
17+
"abi": [
18+
{
19+
"name": "transfer",
20+
"inputs": [
21+
{
22+
"name": "recipientSig",
23+
"type": "sig"
24+
}
25+
]
26+
},
27+
{
28+
"name": "timeout",
29+
"inputs": [
30+
{
31+
"name": "senderSig",
32+
"type": "sig"
33+
}
34+
]
35+
}
36+
],
37+
"bytecode": "OP_3 OP_PICK OP_0 OP_NUMEQUAL OP_IF OP_4 OP_ROLL OP_ROT OP_CHECKSIG OP_NIP OP_NIP OP_NIP OP_ELSE OP_3 OP_ROLL OP_1 OP_NUMEQUALVERIFY OP_3 OP_ROLL OP_SWAP OP_CHECKSIGVERIFY OP_SWAP OP_CHECKLOCKTIMEVERIFY OP_2DROP OP_1 OP_ENDIF",
38+
"source": "pragma cashscript ^0.13.0;\n\ncontract TransferWithTimeout(\n pubkey sender,\n pubkey recipient,\n int timeout\n) {\n // Require recipient's signature to match\n function transfer(sig recipientSig) {\n require(checkSig(recipientSig, recipient));\n }\n\n // Require timeout time to be reached and sender's signature to match\n function timeout(sig senderSig) {\n require(checkSig(senderSig, sender));\n require(tx.time >= timeout);\n }\n}\n",
39+
"debug": {
40+
"bytecode": "5379009c63547a7bac77777767537a519d537a7cad7cb16d5168",
41+
"sourceMap": "9:4:11:5;;;;;10:25:10:37;;:39::48;:8::51:1;9:4:11:5;;;;14::17::0;;;;15:25:15:34;;:36::42;:8::45:1;16:27:16:34:0;:8::36:1;14:4:17:5;;3:0:18:1",
42+
"logs": [],
43+
"requires": [
44+
{
45+
"ip": 12,
46+
"line": 10
47+
},
48+
{
49+
"ip": 23,
50+
"line": 15
51+
},
52+
{
53+
"ip": 25,
54+
"line": 16
55+
}
56+
]
57+
},
58+
"compiler": {
59+
"name": "cashc",
60+
"version": "0.13.0-next.2"
61+
},
62+
"updatedAt": "2026-01-13T10:40:30.007Z"
63+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
pragma cashscript ^0.13.0;
2+
3+
contract TransferWithTimeout(
4+
pubkey sender,
5+
pubkey recipient,
6+
int timeout
7+
) {
8+
// Require recipient's signature to match
9+
function transfer(sig recipientSig) {
10+
require(checkSig(recipientSig, recipient));
11+
}
12+
13+
// Require timeout time to be reached and sender's signature to match
14+
function timeout(sig senderSig) {
15+
require(checkSig(senderSig, sender));
16+
require(tx.time >= timeout);
17+
}
18+
}

examples/testing-suite/package.json

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,14 @@
1212
"test": "test"
1313
},
1414
"scripts": {
15-
"build": "yarn clean && yarn compile",
16-
"clean": "rm -rf ./dist",
17-
"compile": "tsc -p tsconfig.json && yarn run task:compile",
15+
"compile": "tsx tasks/compile.ts",
1816
"lint": "eslint . --ext .ts --ignore-path ../../.eslintignore",
19-
"prepare": "yarn build",
20-
"prepublishOnly": "yarn test && yarn lint",
21-
"task:compile": "tsx tasks/index.ts compile",
22-
"pretest": "yarn run task:compile",
2317
"test": "vitest run"
2418
},
2519
"dependencies": {
2620
"@bitauth/libauth": "^3.1.0-next.8",
2721
"cashc": "^0.13.0-next.2",
28-
"cashscript": "^0.13.0-next.2",
29-
"url-join": "^5.0.0"
22+
"cashscript": "^0.13.0-next.2"
3023
},
3124
"devDependencies": {
3225
"tsx": "^4.20.3",

examples/testing-suite/src/index.ts

Whitespace-only changes.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { formatArtifact } from '@cashscript/utils';
2+
import { compileString } from 'cashc';
3+
import fs from 'fs';
4+
import { URL } from 'url';
5+
6+
export const compile = (): void => {
7+
const directory = new URL('../contracts', import.meta.url);
8+
const result = fs.readdirSync(directory)
9+
.filter((fn) => fn.endsWith('.cash'));
10+
11+
fs.mkdirSync(new URL('../artifacts', import.meta.url), { recursive: true });
12+
13+
result.forEach((fn) => {
14+
const contractFile = new URL(fn, `${directory}/`);
15+
const jsonOutputFile = new URL(`../artifacts/${fn.replace('.cash', '.json')}`, import.meta.url);
16+
const tsOutputFile = new URL(`../artifacts/${fn.replace('.cash', '.artifact.ts')}`, import.meta.url);
17+
18+
try {
19+
const contents = fs.readFileSync(contractFile, { encoding: 'utf-8' });
20+
const artifact = compileString(contents);
21+
22+
fs.writeFileSync(jsonOutputFile, formatArtifact(artifact, 'json'));
23+
fs.writeFileSync(tsOutputFile, formatArtifact(artifact, 'ts'));
24+
} catch (error: any) {
25+
console.error(`Error compiling ${fn}: ${error.message}`);
26+
return;
27+
}
28+
29+
console.log(`Successfully compiled ${fn}`);
30+
});
31+
};
32+
33+
compile();

0 commit comments

Comments
 (0)