@cashscript/utils 0.9.1 → 0.10.0-next.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/artifact.d.ts +19 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/libauth.d.ts +5 -0
- package/dist/libauth.js +50 -0
- package/dist/sourceMap.d.ts +13 -0
- package/dist/sourceMap.js +95 -0
- package/package.json +4 -4
package/dist/artifact.d.ts
CHANGED
|
@@ -9,12 +9,31 @@ export interface AbiFunction {
|
|
|
9
9
|
covenant?: boolean;
|
|
10
10
|
inputs: AbiInput[];
|
|
11
11
|
}
|
|
12
|
+
export interface LogEntry {
|
|
13
|
+
ip: number;
|
|
14
|
+
line: number;
|
|
15
|
+
data: Array<{
|
|
16
|
+
stackIndex: number;
|
|
17
|
+
type: string;
|
|
18
|
+
} | string>;
|
|
19
|
+
}
|
|
20
|
+
export interface RequireMessage {
|
|
21
|
+
ip: number;
|
|
22
|
+
line: number;
|
|
23
|
+
message: string;
|
|
24
|
+
}
|
|
12
25
|
export interface Artifact {
|
|
13
26
|
contractName: string;
|
|
14
27
|
constructorInputs: AbiInput[];
|
|
15
28
|
abi: AbiFunction[];
|
|
16
29
|
bytecode: string;
|
|
17
30
|
source: string;
|
|
31
|
+
debug?: {
|
|
32
|
+
bytecode: string;
|
|
33
|
+
sourceMap: string;
|
|
34
|
+
logs: LogEntry[];
|
|
35
|
+
requireMessages: RequireMessage[];
|
|
36
|
+
};
|
|
18
37
|
compiler: {
|
|
19
38
|
name: string;
|
|
20
39
|
version: string;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/libauth.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { binToHex } from '@bitauth/libauth';
|
|
2
|
+
import { Op } from './script.js';
|
|
3
|
+
import { sourceMapToLocationData } from './sourceMap.js';
|
|
4
|
+
function buildLineMap(bytecode, souceMap) {
|
|
5
|
+
const lineMap = {};
|
|
6
|
+
const locationData = sourceMapToLocationData(souceMap);
|
|
7
|
+
const map = locationData.map(([location, positionHint], index) => {
|
|
8
|
+
const op = bytecode[index];
|
|
9
|
+
return [
|
|
10
|
+
op,
|
|
11
|
+
Object.keys(Op)[Object.values(Op).indexOf(op)],
|
|
12
|
+
positionHint ? location?.end.line : location?.start.line,
|
|
13
|
+
];
|
|
14
|
+
});
|
|
15
|
+
map.forEach(([op, , line]) => {
|
|
16
|
+
if (!lineMap[line]) {
|
|
17
|
+
lineMap[line] = [];
|
|
18
|
+
}
|
|
19
|
+
lineMap[line].push(op);
|
|
20
|
+
});
|
|
21
|
+
return lineMap;
|
|
22
|
+
}
|
|
23
|
+
export function buildOpCodeMap(bytecode, souceMap) {
|
|
24
|
+
const lineMap = buildLineMap(bytecode, souceMap);
|
|
25
|
+
const opCodeMap = {};
|
|
26
|
+
for (const [key, value] of Object.entries(lineMap)) {
|
|
27
|
+
opCodeMap[key] = value.map((asmElement) => {
|
|
28
|
+
if (asmElement instanceof Uint8Array) {
|
|
29
|
+
if (asmElement.length === 0) {
|
|
30
|
+
return 'OP_0';
|
|
31
|
+
}
|
|
32
|
+
return `<0x${binToHex(asmElement)}>`;
|
|
33
|
+
}
|
|
34
|
+
return Object.keys(Op)[Object.values(Op).indexOf(asmElement)];
|
|
35
|
+
}).join(' ');
|
|
36
|
+
}
|
|
37
|
+
return opCodeMap;
|
|
38
|
+
}
|
|
39
|
+
export function formatLibauthScript(bytecode, souceMap, sourceCode) {
|
|
40
|
+
const opCodeMap = buildOpCodeMap(bytecode, souceMap);
|
|
41
|
+
const split = sourceCode.split('\n');
|
|
42
|
+
const maxCodeLength = Math.max(...split.map((val) => val.length));
|
|
43
|
+
const maxBytecodeLength = Math.max(...Object.values(opCodeMap).map((val) => val.length));
|
|
44
|
+
const result = split.map((line, index) => {
|
|
45
|
+
const opCodes = opCodeMap[index + 1];
|
|
46
|
+
return `${(opCodes || '').padEnd(maxBytecodeLength)} /* ${line.padEnd(maxCodeLength)} */`;
|
|
47
|
+
}).join('\n');
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=libauth.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface LocationI {
|
|
2
|
+
start: {
|
|
3
|
+
line: number;
|
|
4
|
+
column: number;
|
|
5
|
+
};
|
|
6
|
+
end: {
|
|
7
|
+
line: number;
|
|
8
|
+
column: number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export declare type LocationData = Array<[location: LocationI, positionHint?: number]>;
|
|
12
|
+
export declare function generateSourceMap(locationData: LocationData): string;
|
|
13
|
+
export declare const sourceMapToLocationData: (sourceMap: string) => LocationData;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The source mappings for the bytecode use the following notation (similar to Solidity):
|
|
3
|
+
*
|
|
4
|
+
* `sl:sc:el:ec:h`
|
|
5
|
+
*
|
|
6
|
+
* Where `sl` is the start line, `sc` - start column, `el` - end line, and `ec` - end column
|
|
7
|
+
* of the range in the source file.
|
|
8
|
+
* `h` is the position hint denoting where to place the instruction - at the beginning of the parent AST block
|
|
9
|
+
* or at the end.
|
|
10
|
+
* `h` is used with AST blocks, instructions of which surround children blocks, like function declarations and
|
|
11
|
+
* if-then-else blocks.
|
|
12
|
+
*
|
|
13
|
+
* Mappings are a list of `sl:sc:el:ec:h` separated by `;`. Each of these elements corresponds to an instruction.
|
|
14
|
+
*
|
|
15
|
+
* In order to compress these source mappings, the following rules are used:
|
|
16
|
+
*
|
|
17
|
+
* If a field is empty, the value of the preceding element is used.
|
|
18
|
+
* If a `:` is missing, all the following fields are considered empty.
|
|
19
|
+
* This means the following source mappings represent the same information:
|
|
20
|
+
*
|
|
21
|
+
* 14:20:14:29;14:20:14:29;14:12:14:30;14:34:14:43;14:34:14:43
|
|
22
|
+
*
|
|
23
|
+
* 14:20:14:29;;:12::30;:34::43;
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
export function generateSourceMap(locationData) {
|
|
27
|
+
let prevStartLine = 0;
|
|
28
|
+
let prevStartColumn = 0;
|
|
29
|
+
let prevEndLine = 0;
|
|
30
|
+
let prevEndColumn = 0;
|
|
31
|
+
let prevHint = 0;
|
|
32
|
+
return locationData.map((row) => {
|
|
33
|
+
const prevStartLineString = prevStartLine === row[0].start.line ? '' : String(row[0].start.line);
|
|
34
|
+
prevStartLine = row[0].start.line;
|
|
35
|
+
const prevStartColumnString = prevStartColumn === row[0].start.column ? '' : String(row[0].start.column);
|
|
36
|
+
prevStartColumn = row[0].start.column;
|
|
37
|
+
const prevEndLineString = prevEndLine === row[0].end.line ? '' : String(row[0].end.line);
|
|
38
|
+
prevEndLine = row[0].end.line;
|
|
39
|
+
const prevEndColumnString = prevEndColumn === row[0].end.column ? '' : String(row[0].end.column);
|
|
40
|
+
prevEndColumn = row[0].end.column;
|
|
41
|
+
const hint = row[1] ?? 0;
|
|
42
|
+
const prevHintString = prevHint === hint ? '' : String(hint);
|
|
43
|
+
prevHint = hint;
|
|
44
|
+
let result = '';
|
|
45
|
+
if (prevStartLineString) {
|
|
46
|
+
result += prevStartLineString;
|
|
47
|
+
}
|
|
48
|
+
result += ':';
|
|
49
|
+
if (prevStartColumnString) {
|
|
50
|
+
result += prevStartColumnString;
|
|
51
|
+
}
|
|
52
|
+
result += ':';
|
|
53
|
+
if (prevEndLineString) {
|
|
54
|
+
result += prevEndLineString;
|
|
55
|
+
}
|
|
56
|
+
result += ':';
|
|
57
|
+
if (prevEndColumnString) {
|
|
58
|
+
result += prevEndColumnString;
|
|
59
|
+
}
|
|
60
|
+
result += ':';
|
|
61
|
+
if (prevHintString) {
|
|
62
|
+
result += prevHintString;
|
|
63
|
+
}
|
|
64
|
+
result = result.replace(/:*$/, '');
|
|
65
|
+
return result;
|
|
66
|
+
}).join(';');
|
|
67
|
+
}
|
|
68
|
+
export const sourceMapToLocationData = (sourceMap) => {
|
|
69
|
+
let prevStartLine = 0;
|
|
70
|
+
let prevStartColumn = 0;
|
|
71
|
+
let prevEndLine = 0;
|
|
72
|
+
let prevEndColumn = 0;
|
|
73
|
+
let prevHint;
|
|
74
|
+
return sourceMap.split(';').map((entry) => {
|
|
75
|
+
const val = entry.split(':');
|
|
76
|
+
const startLine = val[0] ? Number(val[0]) : prevStartLine;
|
|
77
|
+
prevStartLine = startLine;
|
|
78
|
+
const startColumn = val[1] ? Number(val[1]) : prevStartColumn;
|
|
79
|
+
prevStartColumn = startColumn;
|
|
80
|
+
const endLine = val[2] ? Number(val[2]) : prevEndLine;
|
|
81
|
+
prevEndLine = endLine;
|
|
82
|
+
const endColumn = val[3] ? Number(val[3]) : prevEndColumn;
|
|
83
|
+
prevEndColumn = endColumn;
|
|
84
|
+
const hint = val[4] ? Number(val[4]) : prevHint;
|
|
85
|
+
prevHint = hint;
|
|
86
|
+
return [
|
|
87
|
+
{
|
|
88
|
+
start: { line: startLine, column: startColumn },
|
|
89
|
+
end: { line: endLine, column: endColumn },
|
|
90
|
+
},
|
|
91
|
+
...(hint ? [hint] : []),
|
|
92
|
+
];
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=sourceMap.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cashscript/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0-next.0",
|
|
4
4
|
"description": "CashScript utilities and types",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bitcoin cash",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"compile:test": "tsc -p tsconfig.test.json",
|
|
36
36
|
"lint": "eslint . --ext .ts --ignore-path ../../.eslintignore",
|
|
37
37
|
"prepare": "yarn build",
|
|
38
|
-
"prepublishOnly": "yarn test
|
|
38
|
+
"prepublishOnly": "yarn test",
|
|
39
39
|
"pretest": "yarn build:test",
|
|
40
40
|
"test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest"
|
|
41
41
|
},
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@jest/globals": "^29.4.1",
|
|
48
|
-
"eslint": "^
|
|
48
|
+
"eslint": "^8.54.0",
|
|
49
49
|
"jest": "^29.4.1",
|
|
50
50
|
"typescript": "^4.1.5"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "3514c438fa3c8069c36f45cc80730293ac85dbdf"
|
|
53
53
|
}
|