@opcat-labs/cli-opcat 1.0.4 → 1.0.6
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/assets/apply_asm.cjs
CHANGED
|
@@ -1,130 +1,130 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
function replaceFuncBodyAsm(scryptFile, funcName, asm) {
|
|
5
|
-
return new Promise((resolve, reject) => {
|
|
6
|
-
// Buffer to store the characters
|
|
7
|
-
let buffer = '';
|
|
8
|
-
|
|
9
|
-
let pattern = 'function ' + funcName;
|
|
10
|
-
let patternHits = 0;
|
|
11
|
-
let matchActive = false;
|
|
12
|
-
let curlyBraceLevel = 0;
|
|
13
|
-
|
|
14
|
-
// Open the file in read-only mode
|
|
15
|
-
const fileStream = fs.createReadStream(scryptFile, {
|
|
16
|
-
encoding: 'utf8',
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
// Listen for the data event
|
|
20
|
-
fileStream.on('data', (chunk) => {
|
|
21
|
-
for (let i = 0; i < chunk.length; i++) {
|
|
22
|
-
let c = chunk[i];
|
|
23
|
-
|
|
24
|
-
if (matchActive) {
|
|
25
|
-
if (curlyBraceLevel == 0) {
|
|
26
|
-
// Function args
|
|
27
|
-
buffer += c;
|
|
28
|
-
}
|
|
29
|
-
if (c == '{') {
|
|
30
|
-
curlyBraceLevel += 1;
|
|
31
|
-
if (curlyBraceLevel == 1) {
|
|
32
|
-
// First opening curly brace
|
|
33
|
-
// Add ASM here
|
|
34
|
-
buffer += ' asm { ';
|
|
35
|
-
buffer += asm;
|
|
36
|
-
buffer += '}';
|
|
37
|
-
}
|
|
38
|
-
} else if (c == '}') {
|
|
39
|
-
if (curlyBraceLevel == 1) {
|
|
40
|
-
// Closing function curly brace
|
|
41
|
-
buffer += c;
|
|
42
|
-
matchActive = false;
|
|
43
|
-
} else {
|
|
44
|
-
curlyBraceLevel -= 1;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
} else if (c == pattern[patternHits]) {
|
|
48
|
-
patternHits += 1;
|
|
49
|
-
buffer += c;
|
|
50
|
-
|
|
51
|
-
// Check if full pattern match
|
|
52
|
-
if (patternHits == pattern.length) {
|
|
53
|
-
matchActive = true;
|
|
54
|
-
}
|
|
55
|
-
} else {
|
|
56
|
-
patternHits = 0;
|
|
57
|
-
buffer += c;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// Listen for the end event
|
|
63
|
-
fileStream.on('end', () => {
|
|
64
|
-
fs.writeFileSync(scryptFile, buffer);
|
|
65
|
-
resolve();
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
fileStream.on('error', (error) => {
|
|
69
|
-
reject(error);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function getOutDir() {
|
|
75
|
-
let outDir = './artifacts';
|
|
76
|
-
return outDir;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function findFilesWithExtension(directory, extension) {
|
|
80
|
-
const files = fs.readdirSync(directory);
|
|
81
|
-
let foundFiles = [];
|
|
82
|
-
|
|
83
|
-
files.forEach((file) => {
|
|
84
|
-
const filePath = path.join(directory, file);
|
|
85
|
-
const stats = fs.statSync(filePath);
|
|
86
|
-
|
|
87
|
-
if (stats.isDirectory()) {
|
|
88
|
-
const subdirectoryFiles = findFilesWithExtension(filePath, extension);
|
|
89
|
-
foundFiles = foundFiles.concat(subdirectoryFiles);
|
|
90
|
-
} else if (stats.isFile() && file.endsWith(extension)) {
|
|
91
|
-
foundFiles.push(filePath);
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
return foundFiles;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function fileContainsLineStartingWith(filePath, regexPattern) {
|
|
99
|
-
const fileContent = fs.readFileSync(filePath, 'utf8');
|
|
100
|
-
const lines = fileContent.split('\n');
|
|
101
|
-
|
|
102
|
-
const regex = new RegExp(`^(${regexPattern})`);
|
|
103
|
-
return lines.some((line) => regex.test(line.trim()));
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async function main() {
|
|
107
|
-
const asmFile = JSON.parse(fs.readFileSync('.asm/asm.json', 'utf-8'));
|
|
108
|
-
|
|
109
|
-
const outDir = getOutDir();
|
|
110
|
-
const scryptFiles = findFilesWithExtension(outDir, '.scrypt');
|
|
111
|
-
|
|
112
|
-
for (const contractName of Object.keys(asmFile)) {
|
|
113
|
-
let found = false;
|
|
114
|
-
for (const scryptFile of scryptFiles) {
|
|
115
|
-
if (fileContainsLineStartingWith(scryptFile, `(contract|library) ${contractName}`)) {
|
|
116
|
-
found = true;
|
|
117
|
-
for (const func of Object.keys(asmFile[contractName])) {
|
|
118
|
-
const asm = asmFile[contractName][func];
|
|
119
|
-
await replaceFuncBodyAsm(scryptFile, func, asm);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (!found) {
|
|
125
|
-
throw new Error(`Contract ".scrypt" file not found for "${contractName}".`);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
main();
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
function replaceFuncBodyAsm(scryptFile, funcName, asm) {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
// Buffer to store the characters
|
|
7
|
+
let buffer = '';
|
|
8
|
+
|
|
9
|
+
let pattern = 'function ' + funcName;
|
|
10
|
+
let patternHits = 0;
|
|
11
|
+
let matchActive = false;
|
|
12
|
+
let curlyBraceLevel = 0;
|
|
13
|
+
|
|
14
|
+
// Open the file in read-only mode
|
|
15
|
+
const fileStream = fs.createReadStream(scryptFile, {
|
|
16
|
+
encoding: 'utf8',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Listen for the data event
|
|
20
|
+
fileStream.on('data', (chunk) => {
|
|
21
|
+
for (let i = 0; i < chunk.length; i++) {
|
|
22
|
+
let c = chunk[i];
|
|
23
|
+
|
|
24
|
+
if (matchActive) {
|
|
25
|
+
if (curlyBraceLevel == 0) {
|
|
26
|
+
// Function args
|
|
27
|
+
buffer += c;
|
|
28
|
+
}
|
|
29
|
+
if (c == '{') {
|
|
30
|
+
curlyBraceLevel += 1;
|
|
31
|
+
if (curlyBraceLevel == 1) {
|
|
32
|
+
// First opening curly brace
|
|
33
|
+
// Add ASM here
|
|
34
|
+
buffer += ' asm { ';
|
|
35
|
+
buffer += asm;
|
|
36
|
+
buffer += '}';
|
|
37
|
+
}
|
|
38
|
+
} else if (c == '}') {
|
|
39
|
+
if (curlyBraceLevel == 1) {
|
|
40
|
+
// Closing function curly brace
|
|
41
|
+
buffer += c;
|
|
42
|
+
matchActive = false;
|
|
43
|
+
} else {
|
|
44
|
+
curlyBraceLevel -= 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} else if (c == pattern[patternHits]) {
|
|
48
|
+
patternHits += 1;
|
|
49
|
+
buffer += c;
|
|
50
|
+
|
|
51
|
+
// Check if full pattern match
|
|
52
|
+
if (patternHits == pattern.length) {
|
|
53
|
+
matchActive = true;
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
patternHits = 0;
|
|
57
|
+
buffer += c;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Listen for the end event
|
|
63
|
+
fileStream.on('end', () => {
|
|
64
|
+
fs.writeFileSync(scryptFile, buffer);
|
|
65
|
+
resolve();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
fileStream.on('error', (error) => {
|
|
69
|
+
reject(error);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function getOutDir() {
|
|
75
|
+
let outDir = './artifacts';
|
|
76
|
+
return outDir;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function findFilesWithExtension(directory, extension) {
|
|
80
|
+
const files = fs.readdirSync(directory);
|
|
81
|
+
let foundFiles = [];
|
|
82
|
+
|
|
83
|
+
files.forEach((file) => {
|
|
84
|
+
const filePath = path.join(directory, file);
|
|
85
|
+
const stats = fs.statSync(filePath);
|
|
86
|
+
|
|
87
|
+
if (stats.isDirectory()) {
|
|
88
|
+
const subdirectoryFiles = findFilesWithExtension(filePath, extension);
|
|
89
|
+
foundFiles = foundFiles.concat(subdirectoryFiles);
|
|
90
|
+
} else if (stats.isFile() && file.endsWith(extension)) {
|
|
91
|
+
foundFiles.push(filePath);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return foundFiles;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function fileContainsLineStartingWith(filePath, regexPattern) {
|
|
99
|
+
const fileContent = fs.readFileSync(filePath, 'utf8');
|
|
100
|
+
const lines = fileContent.split('\n');
|
|
101
|
+
|
|
102
|
+
const regex = new RegExp(`^(${regexPattern})`);
|
|
103
|
+
return lines.some((line) => regex.test(line.trim()));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function main() {
|
|
107
|
+
const asmFile = JSON.parse(fs.readFileSync('.asm/asm.json', 'utf-8'));
|
|
108
|
+
|
|
109
|
+
const outDir = getOutDir();
|
|
110
|
+
const scryptFiles = findFilesWithExtension(outDir, '.scrypt');
|
|
111
|
+
|
|
112
|
+
for (const contractName of Object.keys(asmFile)) {
|
|
113
|
+
let found = false;
|
|
114
|
+
for (const scryptFile of scryptFiles) {
|
|
115
|
+
if (fileContainsLineStartingWith(scryptFile, `(contract|library) ${contractName}`)) {
|
|
116
|
+
found = true;
|
|
117
|
+
for (const func of Object.keys(asmFile[contractName])) {
|
|
118
|
+
const asm = asmFile[contractName][func];
|
|
119
|
+
await replaceFuncBodyAsm(scryptFile, func, asm);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!found) {
|
|
125
|
+
throw new Error(`Contract ".scrypt" file not found for "${contractName}".`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
main();
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/assets/tsconfig.json
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"lib": ["dom", "dom.iterable", "ES2020"],
|
|
5
|
-
"allowJs": true,
|
|
6
|
-
"skipLibCheck": true,
|
|
7
|
-
"esModuleInterop": true,
|
|
8
|
-
"allowSyntheticDefaultImports": true,
|
|
9
|
-
"strict": true,
|
|
10
|
-
"forceConsistentCasingInFileNames": true,
|
|
11
|
-
"noFallthroughCasesInSwitch": true,
|
|
12
|
-
"module": "commonjs",
|
|
13
|
-
"moduleResolution": "node",
|
|
14
|
-
"resolveJsonModule": true,
|
|
15
|
-
"isolatedModules": true,
|
|
16
|
-
"noEmit": true,
|
|
17
|
-
"experimentalDecorators": true,
|
|
18
|
-
"plugins": []
|
|
19
|
-
},
|
|
20
|
-
"include": ["src/contracts/**/*.ts"],
|
|
21
|
-
"exclude": []
|
|
22
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "ES2020"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"allowSyntheticDefaultImports": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"noFallthroughCasesInSwitch": true,
|
|
12
|
+
"module": "commonjs",
|
|
13
|
+
"moduleResolution": "node",
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"experimentalDecorators": true,
|
|
18
|
+
"plugins": []
|
|
19
|
+
},
|
|
20
|
+
"include": ["src/contracts/**/*.ts"],
|
|
21
|
+
"exclude": []
|
|
22
|
+
}
|
package/bin/main.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
3
|
-
const { bootstrap } = require('../dist/main');
|
|
4
|
-
bootstrap();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
3
|
+
const { bootstrap } = require('../dist/main');
|
|
4
|
+
bootstrap();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opcat-labs/cli-opcat",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "CLI tool for creating and managing sCrypt projects.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"author": "sCrypt.Inc",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@nestjs/common": "^10.0.0",
|
|
30
30
|
"@nestjs/core": "^10.0.0",
|
|
31
31
|
"@nestjs/platform-express": "^10.0.0",
|
|
32
|
-
"@opcat-labs/scrypt-ts-transpiler-opcat": "1.0.
|
|
32
|
+
"@opcat-labs/scrypt-ts-transpiler-opcat": "1.0.5",
|
|
33
33
|
"chalk": "4",
|
|
34
34
|
"envinfo": "^7.14.0",
|
|
35
35
|
"glob": "^11.0.0",
|