@helios-lang/contract-utils 0.1.20 → 0.1.23
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/multi-validator/README.md +5 -0
- package/examples/{spending → multi-validator}/contract.js +7 -2
- package/examples/{spending → multi-validator}/index.d.ts +1 -1
- package/examples/{spending → multi-validator}/index.js +3 -3
- package/examples/{spending → multi-validator}/spending.hl +3 -2
- package/package.json +5 -5
- package/src/{runtime → cast}/Cast.js +31 -8
- package/src/cast/index.js +12 -0
- package/src/codegen/LoadedModule.js +9 -0
- package/src/codegen/{TypescriptWriter.js → LoadedScriptsWriter.js} +117 -107
- package/src/codegen/LoadedValidator.js +23 -0
- package/src/codegen/{Module.js → TypeCheckedModule.js} +3 -3
- package/src/codegen/{Validator.js → TypeCheckedValidator.js} +5 -8
- package/src/codegen/TypeSchema.js +4 -0
- package/src/codegen/index.js +5 -4
- package/src/compiler/CompilerLib.js +51 -0
- package/src/{lib/Libg_v0_16.js → compiler/CompilerLib_v0_16.js} +243 -255
- package/src/compiler/index.js +6 -0
- package/src/compiler/ops.js +137 -0
- package/src/context/ContractContext.js +78 -0
- package/src/context/ContractContextBuilder.js +69 -0
- package/src/context/DagCompiler.js +229 -0
- package/src/context/index.js +1 -0
- package/src/hl2ts.js +31 -59
- package/src/index.js +12 -1
- package/types/cast/Cast.d.ts +32 -0
- package/types/cast/Cast.d.ts.map +1 -0
- package/types/cast/PermissiveType.d.ts +3 -0
- package/types/cast/PermissiveType.d.ts.map +1 -0
- package/types/cast/StrictType.d.ts +3 -0
- package/types/cast/StrictType.d.ts.map +1 -0
- package/types/cast/index.d.ts +5 -0
- package/types/cast/index.d.ts.map +1 -0
- package/types/codegen/LoadedModule.d.ts +6 -0
- package/types/codegen/LoadedModule.d.ts.map +1 -0
- package/types/codegen/LoadedScriptsWriter.d.ts +56 -0
- package/types/codegen/LoadedScriptsWriter.d.ts.map +1 -0
- package/types/codegen/LoadedValidator.d.ts +16 -0
- package/types/codegen/LoadedValidator.d.ts.map +1 -0
- package/types/codegen/TypeCheckedModule.d.ts +11 -0
- package/types/codegen/TypeCheckedModule.d.ts.map +1 -0
- package/types/codegen/TypeCheckedValidator.d.ts +8 -0
- package/types/codegen/TypeCheckedValidator.d.ts.map +1 -0
- package/types/codegen/TypeSchema.d.ts +10 -0
- package/types/codegen/TypeSchema.d.ts.map +1 -1
- package/types/codegen/TypescriptWriter.d.ts +4 -4
- package/types/codegen/Validator.d.ts +1 -1
- package/types/codegen/index.d.ts +5 -4
- package/types/codegen/index.d.ts.map +1 -1
- package/types/compiler/CompilerLib.d.ts +45 -0
- package/types/compiler/CompilerLib.d.ts.map +1 -0
- package/types/compiler/CompilerLib_v0_16.d.ts +270 -0
- package/types/compiler/CompilerLib_v0_16.d.ts.map +1 -0
- package/types/compiler/index.d.ts +4 -0
- package/types/compiler/index.d.ts.map +1 -0
- package/types/compiler/ops.d.ts +24 -0
- package/types/compiler/ops.d.ts.map +1 -0
- package/types/context/ContractContext.d.ts +23 -0
- package/types/context/ContractContext.d.ts.map +1 -0
- package/types/context/ContractContextBuilder.d.ts +53 -0
- package/types/context/ContractContextBuilder.d.ts.map +1 -0
- package/types/context/DagCompiler.d.ts +64 -0
- package/types/context/DagCompiler.d.ts.map +1 -0
- package/types/context/index.d.ts +2 -0
- package/types/context/index.d.ts.map +1 -0
- package/types/hl2ts.d.ts +8 -4
- package/types/hl2ts.d.ts.map +1 -1
- package/types/index.d.ts +4 -1
- package/types/index.d.ts.map +1 -1
- package/types/lib/Lib.d.ts +13 -71
- package/types/lib/Lib.d.ts.map +1 -1
- package/types/lib/Libg_v0_16.d.ts +53 -52
- package/types/lib/Libg_v0_16.d.ts.map +1 -1
- package/types/lib/index.d.ts +0 -1
- package/types/lib/index.d.ts.map +1 -1
- package/types/lib/load.d.ts +1 -7
- package/types/lib/load.d.ts.map +1 -1
- package/types/runtime/ContractContext.d.ts +22 -43
- package/types/runtime/ContractContext.d.ts.map +1 -1
- package/types/runtime/ContractContextBuilder.d.ts +15 -123
- package/types/runtime/ContractContextBuilder.d.ts.map +1 -1
- package/types/runtime/DagCompiler.d.ts +64 -0
- package/types/runtime/DagCompiler.d.ts.map +1 -0
- package/types/runtime/PermissiveType.d.ts +1 -1
- package/types/runtime/StrictType.d.ts +1 -1
- package/types/runtime/index.d.ts +0 -2
- package/src/codegen/Writer.js +0 -37
- package/src/lib/Lib.js +0 -56
- package/src/lib/index.js +0 -6
- package/src/lib/load.js +0 -26
- package/src/runtime/ContractContext.js +0 -35
- package/src/runtime/ContractContextBuilder.js +0 -340
- package/src/runtime/index.js +0 -3
- /package/examples/{spending → multi-validator}/minting.hl +0 -0
- /package/examples/{spending → multi-validator}/package-lock.json +0 -0
- /package/examples/{spending → multi-validator}/package.json +0 -0
- /package/examples/{spending → multi-validator}/utils.hl +0 -0
- /package/src/{runtime → cast}/PermissiveType.js +0 -0
- /package/src/{runtime → cast}/StrictType.js +0 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Codegen multi policy
|
|
2
|
+
|
|
3
|
+
Run `npx hl2ts` to generate Javascript/Typescript equivalents of the `spending.hl` and `minting.hl` validators.
|
|
4
|
+
|
|
5
|
+
Then have a look at `contract.js` to see how these validators can be used within Javascript/Typescript in a type-safe way (ideally using VSCode so you can hover over the types).
|
|
@@ -5,7 +5,10 @@ import { match_string, match_string_policy } from "./index.js"
|
|
|
5
5
|
const context = ContractContextBuilder.new()
|
|
6
6
|
.with(match_string)
|
|
7
7
|
.with(match_string_policy)
|
|
8
|
-
.build(
|
|
8
|
+
.build({
|
|
9
|
+
match_string_policy:
|
|
10
|
+
"f7c8a87011f1aec5967dd3cd68b7a2c26135d750867bfd957b4d8967" // expected hash for match_string_policy
|
|
11
|
+
})
|
|
9
12
|
|
|
10
13
|
console.log(context.match_string_policy.toHex())
|
|
11
14
|
|
|
@@ -13,4 +16,6 @@ const address = Address.fromHash(context.match_string)
|
|
|
13
16
|
|
|
14
17
|
const b = new TxBuilder()
|
|
15
18
|
.mint(context.match_string_policy, [["", 10]], "hello")
|
|
16
|
-
.pay(address,
|
|
19
|
+
.pay(address, 1_000_000n, { hash: { One: { message: "hello" } } })
|
|
20
|
+
// Types from Helios are propagated into Typescript, allowing typesafe conversion of Datums
|
|
21
|
+
.pay(address, 2_000_000n, { hash: { Two: { message: "hello" } } })
|
|
@@ -22,7 +22,7 @@ export const match_string: {
|
|
|
22
22
|
$purpose: "spending"
|
|
23
23
|
$sourceCode: string
|
|
24
24
|
$dependencies: [typeof utils]
|
|
25
|
-
$hashDependencies: []
|
|
25
|
+
$hashDependencies: [typeof match_string_policy]
|
|
26
26
|
$dependsOnOwnHash: boolean
|
|
27
27
|
$Redeemer: Cast<string, string>
|
|
28
28
|
$Datum: Cast<{One: {message: string}} | {Two: {code: bigint}}, {One: {message: string}} | {Two: {code: bigint | number | string}}>
|
|
@@ -18,10 +18,10 @@ export const match_string_policy = {
|
|
|
18
18
|
export const match_string = {
|
|
19
19
|
$name: "match_string",
|
|
20
20
|
$purpose: "spending",
|
|
21
|
-
$sourceCode: "spending match_string\n\nimport { compare } from utils\n\nenum Datum {\n One {\n message: String\n }\n\n Two {\n code: Int\n }\n}\n\nfunc main(datum: Datum, redeemer: String,
|
|
21
|
+
$sourceCode: "spending match_string\n\nimport { compare } from utils\n\nenum Datum {\n One {\n message: String\n }\n\n Two {\n code: Int\n }\n}\n\nfunc main(datum: Datum, redeemer: String, ctx: ScriptContext) -> Bool {\n compare(datum.switch{d: One => d.message, d: Two => d.code.show()}, redeemer) &&\n ctx.tx.minted.get(AssetClass::new(Scripts::match_string_policy, #)) > 0\n}",
|
|
22
22
|
$dependencies: [utils],
|
|
23
|
-
$hashDependencies: [],
|
|
24
|
-
$dependsOnOwnHash:
|
|
23
|
+
$hashDependencies: [match_string_policy],
|
|
24
|
+
$dependsOnOwnHash: true,
|
|
25
25
|
$Redeemer: new Cast({"primitiveType":"String"}),
|
|
26
26
|
$Datum: new Cast({"enumVariantTypes":[{"name":"One","fieldTypes":[{"name":"message","type":{"primitiveType":"String"}}]},{"name":"Two","fieldTypes":[{"name":"code","type":{"primitiveType":"Int"}}]}]})
|
|
27
27
|
}
|
|
@@ -12,6 +12,7 @@ enum Datum {
|
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
func main(datum: Datum, redeemer: String,
|
|
16
|
-
compare(datum.switch{d: One => d.message, d: Two => d.code.show()}, redeemer)
|
|
15
|
+
func main(datum: Datum, redeemer: String, ctx: ScriptContext) -> Bool {
|
|
16
|
+
compare(datum.switch{d: One => d.message, d: Two => d.code.show()}, redeemer) &&
|
|
17
|
+
ctx.tx.minted.get(AssetClass::new(Scripts::match_string_policy, #)) > 0
|
|
17
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.23",
|
|
4
4
|
"description": "Convenience and type-safety utilities for using Helios validators from within Typescript",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "npm run build:types",
|
|
13
13
|
"build:types": "npx tsc -p jsconfig.json --noEmit false --emitDeclarationOnly",
|
|
14
|
-
"
|
|
14
|
+
"prepack": "npm run test:pretty && npm run test:suite && npm run build",
|
|
15
15
|
"prettify": "npx prettier . --write",
|
|
16
16
|
"test": "npm run test:pretty && npm run test:types && npm run test:suite",
|
|
17
17
|
"test:pretty": "npx prettier . --check",
|
|
18
18
|
"test:suite": "node --test --experimental-test-coverage",
|
|
19
|
-
"test:types": "
|
|
19
|
+
"test:types": "npm run build:types"
|
|
20
20
|
},
|
|
21
21
|
"author": "Christian Schmitz",
|
|
22
22
|
"license": "BSD-3-Clause",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"@helios-lang/compiler": "*"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@helios-lang/codec-utils": "^0.1.
|
|
38
|
+
"@helios-lang/codec-utils": "^0.1.27",
|
|
39
39
|
"@helios-lang/compiler-utils": "^0.1.21",
|
|
40
|
-
"@helios-lang/ledger": "^0.1.
|
|
40
|
+
"@helios-lang/ledger": "^0.1.21",
|
|
41
41
|
"@helios-lang/type-utils": "^0.1.8",
|
|
42
42
|
"@helios-lang/uplc": "^0.1.22"
|
|
43
43
|
}
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
AssetClass,
|
|
7
7
|
Credential,
|
|
8
8
|
DatumHash,
|
|
9
|
-
DCert,
|
|
10
9
|
MintingPolicyHash,
|
|
11
10
|
PubKeyHash,
|
|
12
11
|
ScriptHash,
|
|
@@ -26,7 +25,9 @@ import {
|
|
|
26
25
|
IntData,
|
|
27
26
|
ListData,
|
|
28
27
|
MapData,
|
|
28
|
+
decodeBoolData,
|
|
29
29
|
decodeOptionData,
|
|
30
|
+
encodeBoolData,
|
|
30
31
|
encodeOptionData
|
|
31
32
|
} from "@helios-lang/uplc"
|
|
32
33
|
|
|
@@ -36,8 +37,8 @@ import {
|
|
|
36
37
|
*/
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
|
-
* @template [TStrict=
|
|
40
|
-
* @template [TPermissive=
|
|
40
|
+
* @template [TStrict=any]
|
|
41
|
+
* @template [TPermissive=any]
|
|
41
42
|
*/
|
|
42
43
|
export class Cast {
|
|
43
44
|
/**
|
|
@@ -85,7 +86,7 @@ function schemaToUplc(schema, x) {
|
|
|
85
86
|
case "AssetClass":
|
|
86
87
|
return AssetClass.fromAlike(x).toUplcData()
|
|
87
88
|
case "Bool":
|
|
88
|
-
return
|
|
89
|
+
return encodeBoolData(x)
|
|
89
90
|
case "ByteArray":
|
|
90
91
|
return new ByteArrayData(x)
|
|
91
92
|
case "Credential":
|
|
@@ -186,6 +187,7 @@ function schemaToUplc(schema, x) {
|
|
|
186
187
|
}
|
|
187
188
|
|
|
188
189
|
/**
|
|
190
|
+
* This should fail when deviating
|
|
189
191
|
* @param {TypeSchema} schema
|
|
190
192
|
* @param {UplcData} data
|
|
191
193
|
* @returns {any}
|
|
@@ -199,7 +201,7 @@ function uplcToSchema(schema, data) {
|
|
|
199
201
|
// TODO: should this throw an error?
|
|
200
202
|
return null
|
|
201
203
|
case "Bool":
|
|
202
|
-
return
|
|
204
|
+
return decodeBoolData(data, true)
|
|
203
205
|
case "ByteArray":
|
|
204
206
|
return ByteArrayData.expect(data).bytes
|
|
205
207
|
case "Credential":
|
|
@@ -261,8 +263,9 @@ function uplcToSchema(schema, data) {
|
|
|
261
263
|
? uplcToSchema(schema.optionSomeType, optionData)
|
|
262
264
|
: None
|
|
263
265
|
} else if ("structFieldTypes" in schema) {
|
|
266
|
+
const nExpected = schema.structFieldTypes.length
|
|
264
267
|
// TODO: Cip-68 support
|
|
265
|
-
if (
|
|
268
|
+
if (nExpected == 1) {
|
|
266
269
|
return {
|
|
267
270
|
[schema.structFieldTypes[0].name]: uplcToSchema(
|
|
268
271
|
schema.structFieldTypes[0].type,
|
|
@@ -270,10 +273,18 @@ function uplcToSchema(schema, data) {
|
|
|
270
273
|
)
|
|
271
274
|
}
|
|
272
275
|
} else {
|
|
276
|
+
const fields = ListData.expect(data).items
|
|
277
|
+
|
|
278
|
+
if (fields.length != nExpected) {
|
|
279
|
+
throw new Error(
|
|
280
|
+
`expected ${nExpected} fields in struct, got ${fields.length} fields`
|
|
281
|
+
)
|
|
282
|
+
}
|
|
283
|
+
|
|
273
284
|
return Object.fromEntries(
|
|
274
|
-
|
|
285
|
+
fields.map((field, i) => [
|
|
275
286
|
schema.structFieldTypes[i].name,
|
|
276
|
-
uplcToSchema(schema.structFieldTypes[i].type,
|
|
287
|
+
uplcToSchema(schema.structFieldTypes[i].type, field)
|
|
277
288
|
])
|
|
278
289
|
)
|
|
279
290
|
}
|
|
@@ -282,6 +293,18 @@ function uplcToSchema(schema, data) {
|
|
|
282
293
|
|
|
283
294
|
const variantSchema = schema.enumVariantTypes[tag]
|
|
284
295
|
|
|
296
|
+
if (!variantSchema) {
|
|
297
|
+
throw new Error(`tag ${tag} out of range`)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const nExpected = variantSchema.fieldTypes.length
|
|
301
|
+
|
|
302
|
+
if (fields.length != nExpected) {
|
|
303
|
+
throw new Error(
|
|
304
|
+
`expected ${nExpected} fields for variant ${variantSchema.name} (tag ${tag}), got ${fields.length} fields`
|
|
305
|
+
)
|
|
306
|
+
}
|
|
307
|
+
|
|
285
308
|
return {
|
|
286
309
|
[variantSchema.name]: Object.fromEntries(
|
|
287
310
|
fields.map((f, i) => [
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Cast } from "./Cast.js"
|
|
2
|
+
export { Cast }
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @template {Cast} C
|
|
6
|
+
* @typedef {import("./PermissiveType.js").PermissiveType<C>} PermissiveType
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @template {Cast} C
|
|
11
|
+
* @typedef {import("./StrictType.js").StrictType<C>} StrictType
|
|
12
|
+
*/
|
|
@@ -1,121 +1,35 @@
|
|
|
1
|
+
import { StringWriter } from "@helios-lang/codec-utils"
|
|
1
2
|
import { genTypes } from "./TypeSchema.js"
|
|
2
|
-
import { Writer } from "./Writer.js"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @typedef {import("./
|
|
6
|
-
* @typedef {import("./
|
|
5
|
+
* @typedef {import("./TypeCheckedModule.js").TypeCheckedModule} TypeCheckedModule
|
|
6
|
+
* @typedef {import("./TypeCheckedValidator.js").TypeCheckedValidator} TypeCheckedValidator
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
export class
|
|
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
|
-
|
|
9
|
+
export class LoadedScriptsWriter {
|
|
43
10
|
/**
|
|
44
|
-
* @
|
|
11
|
+
* @private
|
|
45
12
|
*/
|
|
46
|
-
|
|
47
|
-
this.
|
|
48
|
-
|
|
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
|
-
)
|
|
13
|
+
constructor() {
|
|
14
|
+
this.definition = new StringWriter()
|
|
15
|
+
this.declaration = new StringWriter()
|
|
63
16
|
}
|
|
64
17
|
|
|
65
18
|
/**
|
|
66
|
-
*
|
|
19
|
+
* Constructs a LoadedScriptsWriter instance and initializes it be writing the header
|
|
20
|
+
* @returns {LoadedScriptsWriter}
|
|
67
21
|
*/
|
|
68
|
-
|
|
69
|
-
const
|
|
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: "${v.name}"
|
|
86
|
-
$purpose: "${v.purpose}"
|
|
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
|
-
}
|
|
22
|
+
static new() {
|
|
23
|
+
const w = new LoadedScriptsWriter()
|
|
100
24
|
|
|
101
|
-
|
|
102
|
-
this.wjs.writeLine(
|
|
103
|
-
'import { Cast } from "@helios-lang/contract-utils";'
|
|
104
|
-
)
|
|
25
|
+
w.writeHeaders()
|
|
105
26
|
|
|
106
|
-
|
|
107
|
-
'import type {UplcData} from "@helios-lang/ledger";'
|
|
108
|
-
)
|
|
109
|
-
this.wdts.writeLine(
|
|
110
|
-
'import { Address, AssetClass, Credential, DatumHash, MintingPolicyHash, PubKeyHash, StakingCredential, StakingHash, StakingValidatorHash, TimeRange, TxId, TxOutputDatum, ValidatorHash, Value} from "@helios-lang/ledger";'
|
|
111
|
-
)
|
|
112
|
-
this.wdts.writeLine(
|
|
113
|
-
'import { Cast } from "@helios-lang/contract-utils";'
|
|
114
|
-
)
|
|
27
|
+
return w
|
|
115
28
|
}
|
|
116
29
|
|
|
117
30
|
/**
|
|
118
|
-
* @param {{[name: string]:
|
|
31
|
+
* @param {{[name: string]: TypeCheckedModule}} ms
|
|
32
|
+
* @returns {LoadedScriptsWriter}
|
|
119
33
|
*/
|
|
120
34
|
writeModules(ms) {
|
|
121
35
|
/**
|
|
@@ -127,7 +41,7 @@ export class TypescriptWriter {
|
|
|
127
41
|
|
|
128
42
|
while (todo.length > 0) {
|
|
129
43
|
/**
|
|
130
|
-
* @type {
|
|
44
|
+
* @type {TypeCheckedModule[]}
|
|
131
45
|
*/
|
|
132
46
|
let todoNext = []
|
|
133
47
|
|
|
@@ -145,11 +59,13 @@ export class TypescriptWriter {
|
|
|
145
59
|
|
|
146
60
|
todo = todoNext
|
|
147
61
|
}
|
|
62
|
+
|
|
63
|
+
return this
|
|
148
64
|
}
|
|
149
65
|
|
|
150
66
|
/**
|
|
151
|
-
*
|
|
152
|
-
* @
|
|
67
|
+
* @param {{[name: string]: TypeCheckedValidator}} validators
|
|
68
|
+
* @returns {LoadedScriptsWriter}
|
|
153
69
|
*/
|
|
154
70
|
writeValidators(validators) {
|
|
155
71
|
/**
|
|
@@ -161,7 +77,7 @@ export class TypescriptWriter {
|
|
|
161
77
|
|
|
162
78
|
while (todo.length > 0) {
|
|
163
79
|
/**
|
|
164
|
-
* @type {
|
|
80
|
+
* @type {TypeCheckedValidator[]}
|
|
165
81
|
*/
|
|
166
82
|
let todoNext = []
|
|
167
83
|
|
|
@@ -181,12 +97,106 @@ export class TypescriptWriter {
|
|
|
181
97
|
|
|
182
98
|
todo = todoNext
|
|
183
99
|
}
|
|
100
|
+
|
|
101
|
+
return this
|
|
184
102
|
}
|
|
185
103
|
|
|
186
104
|
/**
|
|
187
105
|
* @returns {[string, string]}
|
|
188
106
|
*/
|
|
189
107
|
finalize() {
|
|
190
|
-
return [this.
|
|
108
|
+
return [this.definition.finalize(), this.declaration.finalize()]
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @private
|
|
113
|
+
* @param {string} def
|
|
114
|
+
* @param {string} decl
|
|
115
|
+
* @returns {LoadedScriptsWriter}
|
|
116
|
+
*/
|
|
117
|
+
write(def, decl = "") {
|
|
118
|
+
this.definition.write(def)
|
|
119
|
+
this.declaration.write(decl)
|
|
120
|
+
|
|
121
|
+
return this
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @private
|
|
126
|
+
*/
|
|
127
|
+
writeHeaders() {
|
|
128
|
+
this.definition.writeLine(
|
|
129
|
+
'import { Cast } from "@helios-lang/contract-utils";'
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
this.declaration.writeLine(
|
|
133
|
+
'import type {UplcData} from "@helios-lang/ledger";'
|
|
134
|
+
)
|
|
135
|
+
this.declaration.writeLine(
|
|
136
|
+
'import { Address, AssetClass, Credential, DatumHash, MintingPolicyHash, PubKeyHash, StakingCredential, StakingHash, StakingValidatorHash, TimeRange, TxId, TxOutputDatum, ValidatorHash, Value} from "@helios-lang/ledger";'
|
|
137
|
+
)
|
|
138
|
+
this.declaration.writeLine(
|
|
139
|
+
'import { Cast } from "@helios-lang/contract-utils";'
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @private
|
|
145
|
+
* @param {TypeCheckedModule} m
|
|
146
|
+
*/
|
|
147
|
+
writeModule(m) {
|
|
148
|
+
this.write(
|
|
149
|
+
`export const ${m.name} = {
|
|
150
|
+
$name: "${m.name}",
|
|
151
|
+
$purpose: "${m.purpose}",
|
|
152
|
+
$sourceCode: ${JSON.stringify(m.sourceCode)},
|
|
153
|
+
$dependencies: [${m.moduleDepedencies.join(", ")}],
|
|
154
|
+
}
|
|
155
|
+
`,
|
|
156
|
+
`export const ${m.name}: {
|
|
157
|
+
$name: string
|
|
158
|
+
$purpose: string
|
|
159
|
+
$sourceCode: string
|
|
160
|
+
$dependencies: [${m.moduleDepedencies.map((d) => `typeof ${d}`).join(", ")}]
|
|
161
|
+
}
|
|
162
|
+
`
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @private
|
|
168
|
+
* @param {TypeCheckedValidator} v
|
|
169
|
+
*/
|
|
170
|
+
writeValidator(v) {
|
|
171
|
+
const redeemerTypes = genTypes(v.Redeemer)
|
|
172
|
+
const datumTypes = v.Datum ? genTypes(v.Datum) : undefined
|
|
173
|
+
|
|
174
|
+
this.write(
|
|
175
|
+
`export const ${v.name} = {
|
|
176
|
+
$name: "${v.name}",
|
|
177
|
+
$purpose: "${v.purpose}",
|
|
178
|
+
$sourceCode: ${JSON.stringify(v.sourceCode)},
|
|
179
|
+
$dependencies: [${v.moduleDepedencies.join(", ")}],
|
|
180
|
+
$hashDependencies: [${v.hashDependencies.filter((d) => d != v.name).join(", ")}],
|
|
181
|
+
$dependsOnOwnHash: ${v.hashDependencies.some((d) => d == v.name)},
|
|
182
|
+
$Redeemer: new Cast(${JSON.stringify(v.Redeemer)}),
|
|
183
|
+
${datumTypes ? `$Datum: new Cast(${JSON.stringify(v.Datum)})` : ""}
|
|
184
|
+
}
|
|
185
|
+
`,
|
|
186
|
+
`export const ${v.name}: {
|
|
187
|
+
$name: "${v.name}"
|
|
188
|
+
$purpose: "${v.purpose}"
|
|
189
|
+
$sourceCode: string
|
|
190
|
+
$dependencies: [${v.moduleDepedencies.map((d) => `typeof ${d}`).join(", ")}]
|
|
191
|
+
$hashDependencies: [${v.hashDependencies
|
|
192
|
+
.filter((d) => d != v.name)
|
|
193
|
+
.map((d) => `typeof ${d}`)
|
|
194
|
+
.join(", ")}]
|
|
195
|
+
$dependsOnOwnHash: boolean
|
|
196
|
+
$Redeemer: Cast<${redeemerTypes[0]}, ${redeemerTypes[1]}>
|
|
197
|
+
${datumTypes ? `$Datum: Cast<${datumTypes[0]}, ${datumTypes[1]}>` : ""}
|
|
198
|
+
}
|
|
199
|
+
`
|
|
200
|
+
)
|
|
191
201
|
}
|
|
192
202
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Cast } from "../cast/Cast.js"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import("./LoadedModule.js").LoadedModule} LoadedModule
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {{
|
|
9
|
+
* $name: string
|
|
10
|
+
* $sourceCode: string
|
|
11
|
+
* $dependencies: LoadedModule[]
|
|
12
|
+
* $hashDependencies: LoadedValidator[]
|
|
13
|
+
* $dependsOnOwnHash: boolean
|
|
14
|
+
* $Redeemer: Cast
|
|
15
|
+
* } & (
|
|
16
|
+
* {
|
|
17
|
+
* $purpose: "spending"
|
|
18
|
+
* $Datum: Cast
|
|
19
|
+
* } | {
|
|
20
|
+
* $purpose: "minting" | "certifying" | "rewarding" | "staking"
|
|
21
|
+
* }
|
|
22
|
+
* )} LoadedValidator
|
|
23
|
+
*/
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export {}
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* @typedef {import("./TypeSchema.js").TypeSchema} TypeSchema
|
|
3
5
|
*/
|
|
@@ -9,7 +11,5 @@
|
|
|
9
11
|
* sourceCode: string
|
|
10
12
|
* moduleDepedencies: string[]
|
|
11
13
|
* types: {[name: string]: TypeSchema}
|
|
12
|
-
* }}
|
|
14
|
+
* }} TypeCheckedModule
|
|
13
15
|
*/
|
|
14
|
-
|
|
15
|
-
export const _ = {}
|
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
* @typedef {import("./TypeSchema.js").TypeSchema} TypeSchema
|
|
3
|
-
*/
|
|
1
|
+
export {}
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
|
-
* @typedef {import("./
|
|
4
|
+
* @typedef {import("./TypeCheckedModule.js").TypeCheckedModule} TypeCheckedModule
|
|
5
|
+
* @typedef {import("./TypeSchema.js").TypeSchema} TypeSchema
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
|
-
* @typedef {
|
|
9
|
+
* @typedef {TypeCheckedModule & {
|
|
11
10
|
* hashDependencies: string[]
|
|
12
11
|
* Redeemer: TypeSchema
|
|
13
12
|
* Datum?: TypeSchema
|
|
14
|
-
* }}
|
|
13
|
+
* }} TypeCheckedValidator
|
|
15
14
|
*/
|
|
16
|
-
|
|
17
|
-
export const _ = {}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* TODO: references and ids for recursive types and more descriptive codegen
|
|
3
|
+
* TODO: use `kind: "internal" | "list" | "map" | "struct" | "option" | "enum"` instead of `primitiveType` etc.
|
|
4
|
+
* TODO: additional property for struct: `format: "list" | "map"`
|
|
5
|
+
* TODO: rename primitiveType -> internalType
|
|
2
6
|
* @typedef {{
|
|
3
7
|
* primitiveType: string
|
|
4
8
|
* } | {
|
package/src/codegen/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { Writer } from "./Writer.js"
|
|
1
|
+
export { LoadedScriptsWriter } from "./LoadedScriptsWriter.js"
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
|
-
* @typedef {import("./
|
|
4
|
+
* @typedef {import("./LoadedModule.js").LoadedModule} LoadedModule
|
|
5
|
+
* @typedef {import("./LoadedValidator.js").LoadedValidator} LoadedValidator
|
|
6
|
+
* @typedef {import("./TypeCheckedModule.js").TypeCheckedModule} TypeCheckedModule
|
|
7
|
+
* @typedef {import("./TypeCheckedValidator.js").TypeCheckedValidator} TypeCheckedValidator
|
|
6
8
|
* @typedef {import("./TypeSchema.js").TypeSchema} TypeSchema
|
|
7
|
-
* @typedef {import("./Validator.js").Validator} Validator
|
|
8
9
|
*/
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export {}
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import("../codegen/index.js").TypeSchema} InternalTypeDetails
|
|
5
|
+
* @typedef {import("../codegen/index.js").TypeCheckedModule} TypeCheckedModule
|
|
6
|
+
* @typedef {import("../codegen/index.js").TypeCheckedValidator} TypeCheckedValidator
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {{
|
|
11
|
+
* allValidatorHashTypes: {[name: string]: any},
|
|
12
|
+
* hashDependencies: {[name: string]: string},
|
|
13
|
+
* dependsOnOwnHash?: boolean,
|
|
14
|
+
* ownHash?: string,
|
|
15
|
+
* optimize: boolean
|
|
16
|
+
* }} CompileOptions
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {{
|
|
21
|
+
* cborHex: string
|
|
22
|
+
* prettyIR: string
|
|
23
|
+
* }} CompileOutput
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @typedef {{
|
|
28
|
+
* modules: {[name: string]: TypeCheckedModule}
|
|
29
|
+
* validators: {[name: string]: TypeCheckedValidator}
|
|
30
|
+
* }} TypeCheckOutput
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @typedef {{
|
|
35
|
+
* name: string
|
|
36
|
+
* purpose: string
|
|
37
|
+
* sourceCode: string
|
|
38
|
+
* }} SourceDetails
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @typedef {{
|
|
43
|
+
* version: string
|
|
44
|
+
* getScriptHashType: (purpose: string) => any
|
|
45
|
+
* typeCheck: (validators: string[], modules: string[]) => ({
|
|
46
|
+
* modules: {[name: string]: TypeCheckedModule},
|
|
47
|
+
* validators: {[name: string]: TypeCheckedValidator}
|
|
48
|
+
* })
|
|
49
|
+
* compile: (main: string, modules: string[], options: CompileOptions) => CompileOutput
|
|
50
|
+
* }} CompilerLib
|
|
51
|
+
*/
|