@helios-lang/contract-utils 0.1.1 → 0.1.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/examples/spending/app.js +13 -0
- package/examples/spending/output.d.ts +18 -0
- package/examples/spending/output2.d.ts +24 -0
- package/examples/spending/output2.js +34 -0
- package/examples/spending/package-lock.json +39 -0
- package/examples/spending/package.json +7 -0
- package/examples/spending/specialized.js +6 -0
- package/examples/spending/spending.hl +17 -0
- package/examples/spending/unspecialized.js +18 -0
- package/examples/spending/utils.hl +5 -0
- package/package.json +8 -1
- package/src/codegen/Module.js +15 -0
- package/src/codegen/TypeSchema.js +151 -0
- package/src/codegen/TypescriptWriter.js +184 -0
- package/src/codegen/Validator.js +17 -0
- package/src/codegen/Writer.js +37 -0
- package/src/codegen/index.js +8 -0
- package/src/hl2ts.js +172 -2
- package/src/lib/Lib.js +18 -2
- package/src/lib/Libg_v0_16.js +322 -2
- package/src/lib/index.js +1 -1
- package/src/lib/load.js +35 -11
- package/src/runtime/Cast.js +293 -0
- package/.prettierignore +0 -4
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Program } from "@hyperionbt/helios"
|
|
2
|
+
import { utils, match_string } from "./unspecialized.js"
|
|
3
|
+
|
|
4
|
+
const modules = [utils, ...]
|
|
5
|
+
|
|
6
|
+
export class App {
|
|
7
|
+
/**
|
|
8
|
+
* @param {typeof utils} specializedUtils
|
|
9
|
+
*/
|
|
10
|
+
constructor(specializedUtils) {
|
|
11
|
+
this.program = Program.new(match_string, modules.replace("utils", specializedUtils))
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
export const utils: {
|
|
3
|
+
$name: string
|
|
4
|
+
$purpose: string
|
|
5
|
+
$sourceCode: string
|
|
6
|
+
$dependencies: []
|
|
7
|
+
}
|
|
8
|
+
export const match_string: {
|
|
9
|
+
$name: string
|
|
10
|
+
$purpose: string
|
|
11
|
+
$sourceCode: string
|
|
12
|
+
$dependencies: [typeof utils]
|
|
13
|
+
$hashDependencies: []
|
|
14
|
+
$dependsOnOwnHash: boolean
|
|
15
|
+
$Redeemer: Cast<string, string>
|
|
16
|
+
$Datum: Cast<{message: string}, {message: string}>
|
|
17
|
+
}
|
|
18
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export const utils: {
|
|
4
|
+
$name: string
|
|
5
|
+
$purpose: string
|
|
6
|
+
$sourceCode: string
|
|
7
|
+
$dependencies: []
|
|
8
|
+
}
|
|
9
|
+
export const match_string: {
|
|
10
|
+
$name: string
|
|
11
|
+
$purpose: string
|
|
12
|
+
$sourceCode: string
|
|
13
|
+
$dependencies: [typeof utils]
|
|
14
|
+
$hashDependencies: []
|
|
15
|
+
$dependsOnOwnHash: boolean
|
|
16
|
+
$Redeemer: Cast<string, string>
|
|
17
|
+
$Datum: Cast<
|
|
18
|
+
{One: {message: string}} |
|
|
19
|
+
{Two: {code: bigint}},
|
|
20
|
+
{One: {message: string}} |
|
|
21
|
+
{Two: {code: bigint | number | string}}
|
|
22
|
+
>
|
|
23
|
+
}
|
|
24
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const utils = {
|
|
2
|
+
$name: "utils",
|
|
3
|
+
$purpose: "module",
|
|
4
|
+
$sourceCode: "module utils\n\nfunc compare(a: String, b: String) -> Bool {\n a == b\n}",
|
|
5
|
+
$dependencies: [],
|
|
6
|
+
}
|
|
7
|
+
export const match_string = {
|
|
8
|
+
$name: "match_string",
|
|
9
|
+
$purpose: "spending",
|
|
10
|
+
$sourceCode: "spending match_string\n\nimport { compare } from utils\n\nenum Datum {\n One {\n message: String\n }\n\n Two {\n message: String\n }\n}\n\nfunc main(datum: Datum, redeemer: String, _) -> Bool {\n compare(datum.switch{d: One => d.message, d: Two => d.message}, redeemer)\n}",
|
|
11
|
+
$dependencies: [utils],
|
|
12
|
+
$hashDependencies: [],
|
|
13
|
+
$dependsOnOwnHash: false,
|
|
14
|
+
$Redeemer: new Cast({"primitiveType":"String"}),
|
|
15
|
+
$Datum: new Cast({"enumVariantTypes":[{"name":"One","fieldTypes":[{"name":"message","type":{"primitiveType":"String"}}]},{"name":"Two","fieldTypes":[{"name":"message","type":{"primitiveType":"String"}}]}]})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const utils: {
|
|
19
|
+
$name: string
|
|
20
|
+
$purpose: string
|
|
21
|
+
$sourceCode: string
|
|
22
|
+
$dependencies: []
|
|
23
|
+
}
|
|
24
|
+
export const match_string: {
|
|
25
|
+
$name: string
|
|
26
|
+
$purpose: string
|
|
27
|
+
$sourceCode: string
|
|
28
|
+
$dependencies: [typeof utils]
|
|
29
|
+
$hashDependencies: []
|
|
30
|
+
$dependsOnOwnHash: boolean
|
|
31
|
+
$Redeemer: Cast<string, string>
|
|
32
|
+
$Datum: Cast<{One: {message: string}} | {Two: {message: string}}, {One: {message: string}} | {Two: {message: string}}>
|
|
33
|
+
}
|
|
34
|
+
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "spending_example",
|
|
3
|
+
"lockfileVersion": 3,
|
|
4
|
+
"requires": true,
|
|
5
|
+
"packages": {
|
|
6
|
+
"": {
|
|
7
|
+
"name": "spending_example",
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"@helios-lang/contract-utils": "file:../..",
|
|
10
|
+
"@hyperionbt/helios": "^0.16.7"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"../..": {
|
|
14
|
+
"name": "@helios-lang/contract-utils",
|
|
15
|
+
"version": "0.1.1",
|
|
16
|
+
"license": "BSD-3-Clause",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@helios-lang/compiler-utils": "^0.1.2"
|
|
19
|
+
},
|
|
20
|
+
"bin": {
|
|
21
|
+
"hl2ts": "src/hl2ts.js"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "^20.11.24",
|
|
25
|
+
"prettier": "^3.1.0",
|
|
26
|
+
"typescript": "^5.3.2"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"node_modules/@helios-lang/contract-utils": {
|
|
30
|
+
"resolved": "../..",
|
|
31
|
+
"link": true
|
|
32
|
+
},
|
|
33
|
+
"node_modules/@hyperionbt/helios": {
|
|
34
|
+
"version": "0.16.7",
|
|
35
|
+
"resolved": "https://registry.npmjs.org/@hyperionbt/helios/-/helios-0.16.7.tgz",
|
|
36
|
+
"integrity": "sha512-ysPaF0OCY0NJa1mc+LXERjH71VDNGUbYrrovKUHJv1v+eS1WJhKmxSHWh9sVa6b+sYoXdKwoCR20UQhzCF5jzA=="
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
spending match_string
|
|
2
|
+
|
|
3
|
+
import { compare } from "./utils.hl"
|
|
4
|
+
|
|
5
|
+
enum Datum {
|
|
6
|
+
One {
|
|
7
|
+
message: String
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
Two {
|
|
11
|
+
code: Int
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
func main(datum: Datum, redeemer: String, _) -> Bool {
|
|
16
|
+
compare(datum.switch{d: One => d.message, d: Two => d.code.show()}, redeemer)
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Cast } from "@helios-lang/contract-utils"
|
|
2
|
+
|
|
3
|
+
export const utils = {
|
|
4
|
+
$name: "utils",
|
|
5
|
+
$purpose: "module",
|
|
6
|
+
$sourceCode: "module utils\n\nfunc compare(a: String, b: String) -> Bool {\n a == b\n}",
|
|
7
|
+
$dependencies: [],
|
|
8
|
+
}
|
|
9
|
+
export const match_string = {
|
|
10
|
+
$name: "match_string",
|
|
11
|
+
$purpose: "spending",
|
|
12
|
+
$sourceCode: "spending match_string\n\nimport { compare } from utils\n\nstruct Datum {\n message: String\n}\n\nfunc main(datum: Datum, redeemer: String, _) -> Bool {\n compare(datum.message, redeemer)\n}",
|
|
13
|
+
$dependencies: [utils],
|
|
14
|
+
$hashDependencies: [],
|
|
15
|
+
$dependsOnOwnHash: false,
|
|
16
|
+
$Redeemer: new Cast({"primitiveType":"String"}),
|
|
17
|
+
$Datum: new Cast({"structFieldTypes":[{"name":"message","type":{"primitiveType":"String"}}]})
|
|
18
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helios-lang/contract-utils",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Convenience and type-safety utilities for using Helios validators from within Typescript",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -28,5 +28,12 @@
|
|
|
28
28
|
"tabWidth": 4,
|
|
29
29
|
"semi": false,
|
|
30
30
|
"singleQuote": false
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@helios-lang/codec-utils": "^0.1.26",
|
|
34
|
+
"@helios-lang/compiler-utils": "^0.1.20",
|
|
35
|
+
"@helios-lang/ledger": "^0.1.10",
|
|
36
|
+
"@helios-lang/type-utils": "^0.1.8",
|
|
37
|
+
"@helios-lang/uplc": "^0.1.21"
|
|
31
38
|
}
|
|
32
39
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("./TypeSchema.js").TypeSchema} TypeSchema
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {{
|
|
7
|
+
* name: string
|
|
8
|
+
* purpose: string
|
|
9
|
+
* sourceCode: string
|
|
10
|
+
* moduleDepedencies: string[]
|
|
11
|
+
* types: {[name: string]: TypeSchema}
|
|
12
|
+
* }} Module
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export const _ = {}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {{
|
|
3
|
+
* primitiveType: string
|
|
4
|
+
* } | {
|
|
5
|
+
* listItemType: TypeSchema
|
|
6
|
+
* } | {
|
|
7
|
+
* mapKeyType: TypeSchema
|
|
8
|
+
* mapValueType: TypeSchema
|
|
9
|
+
* } | {
|
|
10
|
+
* optionSomeType: TypeSchema
|
|
11
|
+
* } | {
|
|
12
|
+
* structFieldTypes: {
|
|
13
|
+
* name: string
|
|
14
|
+
* type: TypeSchema
|
|
15
|
+
* }[]
|
|
16
|
+
* } | {
|
|
17
|
+
* enumVariantTypes: {
|
|
18
|
+
* name: string,
|
|
19
|
+
* fieldTypes: {
|
|
20
|
+
* name: string
|
|
21
|
+
* type: TypeSchema
|
|
22
|
+
* }[]
|
|
23
|
+
* }[]
|
|
24
|
+
* }} TypeSchema
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {TypeSchema} schema
|
|
29
|
+
* @returns {[string, string]} - the first entry is the canonical type, the second is the permissive type
|
|
30
|
+
*/
|
|
31
|
+
export function genTypes(schema) {
|
|
32
|
+
if ("primitiveType" in schema) {
|
|
33
|
+
switch (schema.primitiveType) {
|
|
34
|
+
case "Address":
|
|
35
|
+
return ["Address", "Address | string"]
|
|
36
|
+
case "Any":
|
|
37
|
+
return ["never", "any"]
|
|
38
|
+
case "AssetClass":
|
|
39
|
+
return [
|
|
40
|
+
"AssetClass",
|
|
41
|
+
"AssetClass | string | [string | MintingPolicyHash | number[], string | number[]] | {mph: MintingPolicyHash | string | number[], tokenName: string | number[]}"
|
|
42
|
+
]
|
|
43
|
+
case "Bool":
|
|
44
|
+
return ["boolean", "boolean"]
|
|
45
|
+
case "ByteArray":
|
|
46
|
+
return ["number[]", "number[]"]
|
|
47
|
+
case "Credential":
|
|
48
|
+
return ["Credential", "Credential | PubKeyHash | ValidatorHash"]
|
|
49
|
+
case "Data":
|
|
50
|
+
return ["UplcData", "UplcData"]
|
|
51
|
+
case "Duration":
|
|
52
|
+
return ["bigint", "bigint | number"]
|
|
53
|
+
case "Int":
|
|
54
|
+
return ["bigint", "bigint | number | string"]
|
|
55
|
+
case "MintingPolicyHash":
|
|
56
|
+
return [
|
|
57
|
+
"MintingPolicyHash",
|
|
58
|
+
"MintingPolicyHash | string | number[]"
|
|
59
|
+
]
|
|
60
|
+
case "PubKey":
|
|
61
|
+
return ["string", "string | number[]"]
|
|
62
|
+
case "PubKeyHash":
|
|
63
|
+
return ["PubKeyHash", "PubKeyHash | string | number[]"]
|
|
64
|
+
case "Real":
|
|
65
|
+
return ["number", "numer"]
|
|
66
|
+
case "StakingCredential":
|
|
67
|
+
return [
|
|
68
|
+
"StakingCredential",
|
|
69
|
+
"StakingCredential | StakingHash | PubKeyHash | StakingValidatorHash"
|
|
70
|
+
]
|
|
71
|
+
case "StakingHash":
|
|
72
|
+
return [
|
|
73
|
+
"StakingHash",
|
|
74
|
+
"StakingHash | PubKeyHash | StakingValidatorHash"
|
|
75
|
+
]
|
|
76
|
+
case "StakingValidatorHash":
|
|
77
|
+
return [
|
|
78
|
+
"StakingValidatorHash",
|
|
79
|
+
"StakingValidatorHash | string | number[]"
|
|
80
|
+
]
|
|
81
|
+
case "String":
|
|
82
|
+
return ["string", "string"]
|
|
83
|
+
case "Time":
|
|
84
|
+
return ["Date", "Date | bigint | number"]
|
|
85
|
+
case "TimeRange":
|
|
86
|
+
return [
|
|
87
|
+
"TimeRange",
|
|
88
|
+
"TimeRange | [Date | number | bigint, Date | number | bigint] | {start?: Date | number | bigint, excludeStart?: boolean, end?: Date | number | bigint, excludeEnd?: boolean}"
|
|
89
|
+
]
|
|
90
|
+
case "TxId":
|
|
91
|
+
return ["TxId", "TxId | string | number[]"]
|
|
92
|
+
case "TxOutputDatum":
|
|
93
|
+
return [
|
|
94
|
+
"TxOutputDatum | null",
|
|
95
|
+
"TxOutputDatum | null | undefined | DatumHash | UplcData"
|
|
96
|
+
]
|
|
97
|
+
case "TxOutputId":
|
|
98
|
+
return ["TxOutputId", "TxOutputId | string"]
|
|
99
|
+
case "ValidatorHash":
|
|
100
|
+
return ["ValidatorHash", "ValidatorHash | string | number[]"]
|
|
101
|
+
case "Value":
|
|
102
|
+
return [
|
|
103
|
+
"Value",
|
|
104
|
+
"Value | [MintingPolicyHash | string | number[], [number[] | string, bigint | number | string][]][] | {mph: MintingPolicyHash | string | number[], tokens: {name: number[] | string, qty: bigint | number | string}[]}[]"
|
|
105
|
+
]
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(
|
|
108
|
+
`unhandled primitive ${schema.primitiveType} in hl2ts`
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
} else if ("listItemType" in schema) {
|
|
112
|
+
const [c, p] = genTypes(schema.listItemType)
|
|
113
|
+
return [`${c}[]`, `${p}[]`]
|
|
114
|
+
} else if ("optionSomeType" in schema) {
|
|
115
|
+
const [c, p] = genTypes(schema.optionSomeType)
|
|
116
|
+
return [`${c} | null`, `${p} | null | undefined`]
|
|
117
|
+
} else if ("mapKeyType" in schema) {
|
|
118
|
+
const [ck, pk] = genTypes(schema.mapKeyType)
|
|
119
|
+
const [cv, pv] = genTypes(schema.mapValueType)
|
|
120
|
+
|
|
121
|
+
return [`Map<${ck}, ${cv}>`, `Map<${pk}, ${pv}> | [${pk}, ${pv}][]`]
|
|
122
|
+
} else if ("structFieldTypes" in schema) {
|
|
123
|
+
const fieldTypes = schema.structFieldTypes.map(({ name, type }) => ({
|
|
124
|
+
name: name,
|
|
125
|
+
types: genTypes(type)
|
|
126
|
+
}))
|
|
127
|
+
|
|
128
|
+
return [
|
|
129
|
+
`{${fieldTypes.map(({ name, types: [c, p] }) => `${name}: ${c}`).join(", ")}}`,
|
|
130
|
+
`{${fieldTypes.map(({ name, types: [c, p] }) => `${name}: ${p}`).join(", ")}}`
|
|
131
|
+
]
|
|
132
|
+
} else if ("enumVariantTypes" in schema) {
|
|
133
|
+
const variantTypes = schema.enumVariantTypes.map(
|
|
134
|
+
({ name, fieldTypes }) => ({
|
|
135
|
+
name: name,
|
|
136
|
+
types: genTypes({ structFieldTypes: fieldTypes })
|
|
137
|
+
})
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
return [
|
|
141
|
+
variantTypes
|
|
142
|
+
.map(({ name, types: [c, p] }) => `{${name}: ${c}}`)
|
|
143
|
+
.join(" | "),
|
|
144
|
+
variantTypes
|
|
145
|
+
.map(({ name, types: [c, p] }) => `{${name}: ${p}}`)
|
|
146
|
+
.join(" | ")
|
|
147
|
+
]
|
|
148
|
+
} else {
|
|
149
|
+
throw new Error(`unhandled TypeSchema ${JSON.stringify(schema)}`)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { genTypes } from "./TypeSchema.js"
|
|
2
|
+
import { Writer } from "./Writer.js"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import("./Module.js").Module} Module
|
|
6
|
+
* @typedef {import("./Validator.js").Validator} Validator
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export class TypescriptWriter {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.wjs = new Writer()
|
|
12
|
+
this.wdts = new Writer()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} js
|
|
17
|
+
* @param {string} dts
|
|
18
|
+
* @returns {TypescriptWriter}
|
|
19
|
+
*/
|
|
20
|
+
write(js, dts = "") {
|
|
21
|
+
this.wjs.write(js)
|
|
22
|
+
this.wdts.write(dts)
|
|
23
|
+
return this
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {string} js
|
|
28
|
+
* @param {string} dts
|
|
29
|
+
* @returns {TypescriptWriter}
|
|
30
|
+
*/
|
|
31
|
+
writeLine(js, dts = "") {
|
|
32
|
+
if (js != "") {
|
|
33
|
+
this.wjs.writeLine(js)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (dts != "") {
|
|
37
|
+
this.wdts.writeLine(dts)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return this
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param {Module} m
|
|
45
|
+
*/
|
|
46
|
+
writeModule(m) {
|
|
47
|
+
this.write(
|
|
48
|
+
`export const ${m.name} = {
|
|
49
|
+
$name: "${m.name}",
|
|
50
|
+
$purpose: "${m.purpose}",
|
|
51
|
+
$sourceCode: ${JSON.stringify(m.sourceCode)},
|
|
52
|
+
$dependencies: [${m.moduleDepedencies.join(", ")}],
|
|
53
|
+
}
|
|
54
|
+
`,
|
|
55
|
+
`export const ${m.name}: {
|
|
56
|
+
$name: string
|
|
57
|
+
$purpose: string
|
|
58
|
+
$sourceCode: string
|
|
59
|
+
$dependencies: [${m.moduleDepedencies.map((d) => `typeof ${d}`).join(", ")}]
|
|
60
|
+
}
|
|
61
|
+
`
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @param {Validator} v
|
|
67
|
+
*/
|
|
68
|
+
writeValidator(v) {
|
|
69
|
+
const redeemerTypes = genTypes(v.Redeemer)
|
|
70
|
+
const datumTypes = v.Datum ? genTypes(v.Datum) : undefined
|
|
71
|
+
|
|
72
|
+
this.write(
|
|
73
|
+
`export const ${v.name} = {
|
|
74
|
+
$name: "${v.name}",
|
|
75
|
+
$purpose: "${v.purpose}",
|
|
76
|
+
$sourceCode: ${JSON.stringify(v.sourceCode)},
|
|
77
|
+
$dependencies: [${v.moduleDepedencies.join(", ")}],
|
|
78
|
+
$hashDependencies: [${v.hashDependencies.filter((d) => d != v.name).join(", ")}],
|
|
79
|
+
$dependsOnOwnHash: ${v.hashDependencies.some((d) => d == v.name)},
|
|
80
|
+
$Redeemer: new Cast(${JSON.stringify(v.Redeemer)}),
|
|
81
|
+
${datumTypes ? `$Datum: new Cast(${JSON.stringify(v.Datum)})` : ""}
|
|
82
|
+
}
|
|
83
|
+
`,
|
|
84
|
+
`export const ${v.name}: {
|
|
85
|
+
$name: string
|
|
86
|
+
$purpose: string
|
|
87
|
+
$sourceCode: string
|
|
88
|
+
$dependencies: [${v.moduleDepedencies.map((d) => `typeof ${d}`).join(", ")}]
|
|
89
|
+
$hashDependencies: [${v.hashDependencies
|
|
90
|
+
.filter((d) => d != v.name)
|
|
91
|
+
.map((d) => `typeof ${d}`)
|
|
92
|
+
.join(", ")}]
|
|
93
|
+
$dependsOnOwnHash: boolean
|
|
94
|
+
$Redeemer: Cast<${redeemerTypes[0]}, ${redeemerTypes[1]}>
|
|
95
|
+
${datumTypes ? `$Datum: Cast<${datumTypes[0]}, ${datumTypes[1]}>` : ""}
|
|
96
|
+
}
|
|
97
|
+
`
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
writeHeaders() {
|
|
102
|
+
this.wjs.writeLine("import { Cast } from \"@helios-lang/contract-utils\";")
|
|
103
|
+
|
|
104
|
+
this.wdts.writeLine("import type {UplcData} from \"@helios-lang/ledger\";")
|
|
105
|
+
this.wdts.writeLine("import { Address, AssetClass, Credential, DatumHash, MintingPolicyHash, PubKeyHash, StakingCredential, StakingHash, StakingValidatorHash, TimeRange, TxId, TxOutputDatum, ValidatorHash, Value} from \"@helios-lang/ledger\";")
|
|
106
|
+
this.wdts.writeLine("import { Cast } from \"@helios-lang/contract-utils\";")
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param {{[name: string]: Module}} ms
|
|
111
|
+
*/
|
|
112
|
+
writeModules(ms) {
|
|
113
|
+
/**
|
|
114
|
+
* @type {Set<string>}
|
|
115
|
+
*/
|
|
116
|
+
const done = new Set()
|
|
117
|
+
|
|
118
|
+
let todo = Object.values(ms)
|
|
119
|
+
|
|
120
|
+
while (todo.length > 0) {
|
|
121
|
+
/**
|
|
122
|
+
* @type {Module[]}
|
|
123
|
+
*/
|
|
124
|
+
let todoNext = []
|
|
125
|
+
|
|
126
|
+
for (let i = 0; i < todo.length; i++) {
|
|
127
|
+
const m = todo[i]
|
|
128
|
+
|
|
129
|
+
if (m.moduleDepedencies.every((d) => done.has(d))) {
|
|
130
|
+
this.writeModule(m)
|
|
131
|
+
|
|
132
|
+
done.add(m.name)
|
|
133
|
+
} else {
|
|
134
|
+
todoNext.push(m)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
todo = todoNext
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
*
|
|
144
|
+
* @param {{[name: string]: Validator}} validators
|
|
145
|
+
*/
|
|
146
|
+
writeValidators(validators) {
|
|
147
|
+
/**
|
|
148
|
+
* @type {Set<string>}
|
|
149
|
+
*/
|
|
150
|
+
const done = new Set()
|
|
151
|
+
|
|
152
|
+
let todo = Object.values(validators)
|
|
153
|
+
|
|
154
|
+
while (todo.length > 0) {
|
|
155
|
+
/**
|
|
156
|
+
* @type {Validator[]}
|
|
157
|
+
*/
|
|
158
|
+
let todoNext = []
|
|
159
|
+
|
|
160
|
+
for (let i = 0; i < todo.length; i++) {
|
|
161
|
+
const v = todo[i]
|
|
162
|
+
|
|
163
|
+
if (
|
|
164
|
+
v.hashDependencies.every((d) => done.has(d) || d == v.name)
|
|
165
|
+
) {
|
|
166
|
+
this.writeValidator(v)
|
|
167
|
+
|
|
168
|
+
done.add(v.name)
|
|
169
|
+
} else {
|
|
170
|
+
todoNext.push(v)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
todo = todoNext
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @returns {[string, string]}
|
|
180
|
+
*/
|
|
181
|
+
finalize() {
|
|
182
|
+
return [this.wjs.finalize(), this.wdts.finalize()]
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("./TypeSchema.js").TypeSchema} TypeSchema
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {import("./Module.js").Module} Module
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Module & {
|
|
11
|
+
* hashDependencies: string[]
|
|
12
|
+
* Redeemer: TypeSchema
|
|
13
|
+
* Datum?: TypeSchema
|
|
14
|
+
* }} Validator
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export const _ = {}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export class Writer {
|
|
2
|
+
/**
|
|
3
|
+
* @private
|
|
4
|
+
* @readonly
|
|
5
|
+
* @type {string[]}
|
|
6
|
+
*/
|
|
7
|
+
parts
|
|
8
|
+
|
|
9
|
+
constructor() {
|
|
10
|
+
this.parts = []
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {string} part
|
|
15
|
+
* @returns {Writer}
|
|
16
|
+
*/
|
|
17
|
+
write(part) {
|
|
18
|
+
this.parts.push(part)
|
|
19
|
+
return this
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {string} line
|
|
24
|
+
* @returns {Writer}
|
|
25
|
+
*/
|
|
26
|
+
writeLine(line) {
|
|
27
|
+
this.parts.push(`${line}\n`)
|
|
28
|
+
return this
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @returns {string}
|
|
33
|
+
*/
|
|
34
|
+
finalize() {
|
|
35
|
+
return this.parts.join("")
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { TypescriptWriter } from "./TypescriptWriter.js"
|
|
2
|
+
export { Writer } from "./Writer.js"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import("./Module.js").Module} Module
|
|
6
|
+
* @typedef {import("./TypeSchema.js").TypeSchema} TypeSchema
|
|
7
|
+
* @typedef {import("./Validator.js").Validator} Validator
|
|
8
|
+
*/
|