@helios-lang/contract-utils 0.2.8 → 0.2.10

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.
@@ -1,158 +1,154 @@
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
6
- * @typedef {{
7
- * primitiveType: string
8
- * } | {
9
- * listItemType: TypeSchema
10
- * } | {
11
- * mapKeyType: TypeSchema
12
- * mapValueType: TypeSchema
13
- * } | {
14
- * optionSomeType: TypeSchema
15
- * } | {
16
- * structFieldTypes: {
17
- * name: string
18
- * type: TypeSchema
19
- * }[]
20
- * } | {
21
- * enumVariantTypes: {
22
- * name: string,
23
- * fieldTypes: {
24
- * name: string
25
- * type: TypeSchema
26
- * }[]
27
- * }[]
28
- * }} TypeSchema
2
+ * @typedef {import("@helios-lang/type-utils").TypeSchema} TypeSchema
29
3
  */
30
4
 
31
5
  /**
6
+ * TODO: handle recursive data structures
32
7
  * @param {TypeSchema} schema
33
8
  * @returns {[string, string]} - the first entry is the canonical type, the second is the permissive type
34
9
  */
35
10
  export function genTypes(schema) {
36
- if ("primitiveType" in schema) {
37
- switch (schema.primitiveType) {
38
- case "Address":
39
- return ["Address", "Address | string"]
40
- case "Any":
41
- return ["never", "any"]
42
- case "AssetClass":
43
- return [
44
- "AssetClass",
45
- "AssetClass | string | [string | MintingPolicyHash | number[], string | number[]] | {mph: MintingPolicyHash | string | number[], tokenName: string | number[]}"
46
- ]
47
- case "Bool":
48
- return ["boolean", "boolean"]
49
- case "ByteArray":
50
- return ["number[]", "number[]"]
51
- case "SpendingCredential":
52
- return [
53
- "SpendingCredential",
54
- "SpendingCredential | PubKeyHash | ValidatorHash"
55
- ]
56
- case "Data":
57
- return ["UplcData", "UplcData"]
58
- case "Duration":
59
- return ["bigint", "IntLike"]
60
- case "Int":
61
- return ["bigint", "IntLike"]
62
- case "MintingPolicyHash":
63
- return [
64
- "MintingPolicyHash",
65
- "MintingPolicyHash | string | number[]"
66
- ]
67
- case "PubKey":
68
- return ["PubKey", "PubKey | string | number[]"]
69
- case "PubKeyHash":
70
- return ["PubKeyHash", "PubKeyHash | string | number[]"]
71
- case "Real":
72
- return ["number", "number"]
73
- case "StakingCredential":
74
- return [
75
- "StakingCredential",
76
- "StakingCredential | StakingHash | PubKeyHash | StakingValidatorHash"
77
- ]
78
- case "StakingHash":
79
- return [
80
- "StakingHash",
81
- "StakingHash | PubKeyHash | StakingValidatorHash"
82
- ]
83
- case "StakingValidatorHash":
84
- return [
85
- "StakingValidatorHash",
86
- "StakingValidatorHash | string | number[]"
87
- ]
88
- case "String":
89
- return ["string", "string"]
90
- case "Time":
91
- return ["number", "TimeLike"]
92
- case "TimeRange":
93
- return [
94
- "TimeRange",
95
- "TimeRange | [TimeLike, TimeLike] | {start?: TimeLike, excludeStart?: boolean, end?: TimeLike, excludeEnd?: boolean}"
96
- ]
97
- case "TxId":
98
- return ["TxId", "TxId | string | number[]"]
99
- case "TxOutputDatum":
100
- return [
101
- "TxOutputDatum | null",
102
- "TxOutputDatum | null | undefined | DatumHash | UplcData"
103
- ]
104
- case "TxOutputId":
105
- return ["TxOutputId", "TxOutputId | string"]
106
- case "ValidatorHash":
107
- return ["ValidatorHash", "ValidatorHash | string | number[]"]
108
- case "Value":
109
- return [
110
- "Value",
111
- "Value | [MintingPolicyHash | string | number[], [number[] | string, IntLike][]][] | {mph: MintingPolicyHash | string | number[], tokens: {name: number[] | string, qty: IntLike}[]}[]"
112
- ]
113
- default:
114
- throw new Error(
115
- `unhandled primitive ${schema.primitiveType} in hl2ts`
116
- )
11
+ const kind = schema.kind
12
+
13
+ switch (kind) {
14
+ case "internal":
15
+ const name = schema.name
16
+ switch (name) {
17
+ case "Address":
18
+ return ["Address", "Address | string"]
19
+ case "AssetClass":
20
+ return [
21
+ "AssetClass",
22
+ "AssetClass | string | [string | MintingPolicyHash | number[], string | number[]] | {mph: MintingPolicyHash | string | number[], tokenName: string | number[]}"
23
+ ]
24
+ case "Bool":
25
+ return ["boolean", "boolean"]
26
+ case "ByteArray":
27
+ return ["number[]", "number[]"]
28
+ case "Data":
29
+ return ["UplcData", "UplcData"]
30
+ case "Duration":
31
+ return ["bigint", "IntLike"]
32
+ case "Int":
33
+ return ["bigint", "IntLike"]
34
+ case "MintingPolicyHash":
35
+ return [
36
+ "MintingPolicyHash",
37
+ "MintingPolicyHash | string | number[]"
38
+ ]
39
+ case "PubKey":
40
+ return ["PubKey", "PubKey | string | number[]"]
41
+ case "PubKeyHash":
42
+ return ["PubKeyHash", "PubKeyHash | string | number[]"]
43
+ case "Real":
44
+ return ["number", "number"]
45
+ case "SpendingCredential":
46
+ return [
47
+ "SpendingCredential",
48
+ "SpendingCredential | PubKeyHash | ValidatorHash"
49
+ ]
50
+ case "StakingCredential":
51
+ return [
52
+ "StakingCredential",
53
+ "StakingCredential | StakingHash | PubKeyHash | StakingValidatorHash"
54
+ ]
55
+ case "StakingHash":
56
+ return [
57
+ "StakingHash",
58
+ "StakingHash | PubKeyHash | StakingValidatorHash"
59
+ ]
60
+ case "StakingValidatorHash":
61
+ return [
62
+ "StakingValidatorHash",
63
+ "StakingValidatorHash | string | number[]"
64
+ ]
65
+ case "String":
66
+ return ["string", "string"]
67
+
68
+ case "Time":
69
+ return ["number", "TimeLike"]
70
+ case "TimeRange":
71
+ return [
72
+ "TimeRange",
73
+ "TimeRange | [TimeLike, TimeLike] | {start?: TimeLike, excludeStart?: boolean, end?: TimeLike, excludeEnd?: boolean}"
74
+ ]
75
+ case "TxId":
76
+ return ["TxId", "TxId | string | number[]"]
77
+ case "TxOutputDatum":
78
+ return [
79
+ "TxOutputDatum | null",
80
+ "TxOutputDatum | null | undefined | DatumHash | UplcData"
81
+ ]
82
+ case "TxOutputId":
83
+ return ["TxOutputId", "TxOutputId | string"]
84
+ case "ValidatorHash":
85
+ return [
86
+ "ValidatorHash",
87
+ "ValidatorHash | string | number[]"
88
+ ]
89
+ case "Value":
90
+ return [
91
+ "Value",
92
+ "Value | [MintingPolicyHash | string | number[], [number[] | string, IntLike][]][] | {mph: MintingPolicyHash | string | number[], tokens: {name: number[] | string, qty: IntLike}[]}[]"
93
+ ]
94
+ default:
95
+ throw new Error(`unhandled primitive '${name}' in hl2ts`)
96
+ }
97
+ case "list": {
98
+ const [c, p] = genTypes(schema.itemType)
99
+ return [`(${c})[]`, `(${p})[]`]
117
100
  }
118
- } else if ("listItemType" in schema) {
119
- const [c, p] = genTypes(schema.listItemType)
120
- return [`(${c})[]`, `(${p})[]`]
121
- } else if ("optionSomeType" in schema) {
122
- const [c, p] = genTypes(schema.optionSomeType)
123
- return [`(${c}) | null`, `(${p}) | null | undefined`]
124
- } else if ("mapKeyType" in schema) {
125
- const [ck, pk] = genTypes(schema.mapKeyType)
126
- const [cv, pv] = genTypes(schema.mapValueType)
101
+ case "map": {
102
+ const [ck, pk] = genTypes(schema.keyType)
103
+ const [cv, pv] = genTypes(schema.valueType)
127
104
 
128
- return [`Map<${ck}, ${cv}>`, `Map<${pk}, ${pv}> | [${pk}, ${pv}][]`]
129
- } else if ("structFieldTypes" in schema) {
130
- const fieldTypes = schema.structFieldTypes.map(({ name, type }) => ({
131
- name: name,
132
- types: genTypes(type)
133
- }))
105
+ return [`Map<${ck}, ${cv}>`, `Map<${pk}, ${pv}> | [${pk}, ${pv}][]`]
106
+ }
107
+ case "option": {
108
+ const [c, p] = genTypes(schema.someType)
109
+ return [`(${c}) | null`, `(${p}) | null | undefined`]
110
+ }
111
+ case "struct": {
112
+ const fieldTypes = schema.fieldTypes.map(({ name, type }) => ({
113
+ name: name,
114
+ types: genTypes(type)
115
+ }))
134
116
 
135
- return [
136
- `{${fieldTypes.map(({ name, types: [c, p] }) => `${name}: ${c}`).join(", ")}}`,
137
- `{${fieldTypes.map(({ name, types: [c, p] }) => `${name}: ${p}`).join(", ")}}`
138
- ]
139
- } else if ("enumVariantTypes" in schema) {
140
- const variantTypes = schema.enumVariantTypes.map(
141
- ({ name, fieldTypes }) => ({
117
+ return [
118
+ `{${fieldTypes.map(({ name, types: [c, p] }) => `${name}: ${c}`).join(", ")}}`,
119
+ `{${fieldTypes.map(({ name, types: [c, p] }) => `${name}: ${p}`).join(", ")}}`
120
+ ]
121
+ }
122
+ case "enum": {
123
+ const variantTypes = schema.variantTypes.map((variant) => ({
124
+ name: variant.name,
125
+ types: genTypes(variant)
126
+ }))
127
+
128
+ return [
129
+ variantTypes
130
+ .map(({ name, types: [c, p] }) => `{${name}: ${c}}`)
131
+ .join(" | "),
132
+ variantTypes
133
+ .map(({ name, types: [c, p] }) => `{${name}: ${p}}`)
134
+ .join(" | ")
135
+ ]
136
+ }
137
+ case "variant": {
138
+ // similar to structure
139
+ const fieldTypes = schema.fieldTypes.map(({ name, type }) => ({
142
140
  name: name,
143
- types: genTypes({ structFieldTypes: fieldTypes })
144
- })
145
- )
141
+ types: genTypes(type)
142
+ }))
146
143
 
147
- return [
148
- variantTypes
149
- .map(({ name, types: [c, p] }) => `{${name}: ${c}}`)
150
- .join(" | "),
151
- variantTypes
152
- .map(({ name, types: [c, p] }) => `{${name}: ${p}}`)
153
- .join(" | ")
154
- ]
155
- } else {
156
- throw new Error(`unhandled TypeSchema ${JSON.stringify(schema)}`)
144
+ return [
145
+ `{${fieldTypes.map(({ name, types: [c, p] }) => `${name}: ${c}`).join(", ")}}`,
146
+ `{${fieldTypes.map(({ name, types: [c, p] }) => `${name}: ${p}`).join(", ")}}`
147
+ ]
148
+ }
149
+ case "reference":
150
+ throw new Error("recursive data structures not yet handled")
151
+ default:
152
+ throw new Error(`unhandled TypeSchema kind '${kind}'`)
157
153
  }
158
154
  }
@@ -1,18 +1,26 @@
1
+ import { readHeader } from "@helios-lang/compiler-utils"
2
+
1
3
  export {}
2
4
 
3
5
  /**
6
+ * @typedef {import("@helios-lang/uplc").UplcData} UplcData
4
7
  * @typedef {import("../codegen/index.js").TypeSchema} InternalTypeDetails
5
8
  * @typedef {import("../codegen/index.js").TypeCheckedModule} TypeCheckedModule
6
9
  * @typedef {import("../codegen/index.js").TypeCheckedValidator} TypeCheckedValidator
7
10
  */
8
11
 
12
+ /**
13
+ * @typedef {any} ScriptHashType
14
+ */
15
+
9
16
  /**
10
17
  * @typedef {{
11
- * allValidatorHashTypes: {[name: string]: any}
18
+ * allValidatorHashTypes: {[name: string]: ScriptHashType}
12
19
  * hashDependencies: {[name: string]: string}
13
20
  * dependsOnOwnHash?: boolean
14
21
  * ownHash?: string
15
- * parameters?: Record<string, any>
22
+ * parameters?: Record<string, UplcData>
23
+ * isTestnet: boolean
16
24
  * optimize: boolean
17
25
  * }} CompileOptions
18
26
  */
@@ -20,7 +28,6 @@ export {}
20
28
  /**
21
29
  * @typedef {{
22
30
  * cborHex: string
23
- * prettyIR: string
24
31
  * }} CompileOutput
25
32
  */
26
33
 
@@ -42,7 +49,7 @@ export {}
42
49
  /**
43
50
  * @typedef {{
44
51
  * version: string
45
- * getScriptHashType: (purpose: string) => any
52
+ * getScriptHashType: (purpose: string) => ScriptHashType
46
53
  * typeCheck: (validators: string[], modules: string[]) => ({
47
54
  * modules: {[name: string]: TypeCheckedModule},
48
55
  * validators: {[name: string]: TypeCheckedValidator}
@@ -50,3 +57,21 @@ export {}
50
57
  * compile: (main: string, modules: string[], options: CompileOptions) => CompileOutput
51
58
  * }} CompilerLib
52
59
  */
60
+
61
+ /**
62
+ * @typedef {Record<string, string[]>} DagDependencies
63
+ */
64
+
65
+ /**
66
+ * @param {CompilerLib} lib
67
+ * @param {string[]} validators
68
+ * @returns {{[name: string]: ScriptHashType}}
69
+ */
70
+ export function getValidatorTypes(lib, validators) {
71
+ return Object.fromEntries(
72
+ validators.map((src) => {
73
+ const [purpose, name] = readHeader(src)
74
+ return [name, lib.getScriptHashType(purpose)]
75
+ })
76
+ )
77
+ }
@@ -1,29 +1,22 @@
1
- import { bytesToHex } from "@helios-lang/compiler"
1
+ import { bytesToHex } from "@helios-lang/codec-utils"
2
2
  import { readHeader } from "@helios-lang/compiler-utils"
3
3
  import { expectSome } from "@helios-lang/type-utils"
4
+ import { getValidatorTypes } from "./CompilerLib.js"
4
5
 
5
6
  /**
7
+ * @typedef {import("@helios-lang/uplc").UplcData} UplcData
6
8
  * @typedef {import("../codegen/index.js").TypeCheckedModule} TypeCheckedModule
7
9
  * @typedef {import("../codegen/index.js").TypeCheckedValidator} TypeCheckedValidator
8
- * @typedef {import("../codegen/index.js").TypeSchema} InternalTypeDetails
10
+ * @typedef {import("../codegen/index.js").TypeSchema} TypeSchema
9
11
  * @typedef {import("./CompilerLib.js").CompileOptions} CompileOptions
10
12
  * @typedef {import("./CompilerLib.js").CompileOutput} CompileOutput
11
13
  * @typedef {import("./CompilerLib.js").CompilerLib} CompilerLib
14
+ * @typedef {import("./CompilerLib.js").DagDependencies} DagDependencies
15
+ * @typedef {import("./CompilerLib.js").ScriptHashType} ScriptHashType
12
16
  * @typedef {import("./CompilerLib.js").SourceDetails} SourceDetails
13
17
  * @typedef {import("./CompilerLib.js").TypeCheckOutput} TypeCheckOutput
14
18
  */
15
19
 
16
- /**
17
- * @typedef {{
18
- * [name: string]: string[]
19
- * }} DagDependencies
20
- */
21
-
22
- /**
23
- * @typedef {{
24
- * }} ScriptHashType
25
- */
26
-
27
20
  /**
28
21
  * @typedef {{
29
22
  * includes: (m: string) => boolean
@@ -101,34 +94,34 @@ import { expectSome } from "@helios-lang/type-utils"
101
94
  * type: string
102
95
  * } | {
103
96
  * type: "List"
104
- * itemType: TypeSchema
97
+ * itemType: TypeSchema16
105
98
  * } | {
106
99
  * type: "Map"
107
- * keyType: TypeSchema
108
- * valueType: TypeSchema
100
+ * keyType: TypeSchema16
101
+ * valueType: TypeSchema16
109
102
  * } | {
110
103
  * type: "Option"
111
- * someType: TypeSchema
104
+ * someType: TypeSchema16
112
105
  * } | {
113
106
  * type: "Struct"
114
- * fieldTypes: NamedTypeSchema[]
107
+ * fieldTypes: NamedTypeSchema16[]
115
108
  * } | {
116
109
  * type: "Enum"
117
- * variantTypes: {name: string, fieldTypes: NamedTypeSchema[]}[]
118
- * }} TypeSchema
110
+ * variantTypes: {name: string, fieldTypes: NamedTypeSchema16[]}[]
111
+ * }} TypeSchema16
119
112
  */
120
113
 
121
114
  /**
122
115
  * @typedef {{
123
116
  * name: string
124
- * } & TypeSchema} NamedTypeSchema
117
+ * } & TypeSchema16} NamedTypeSchema16
125
118
  */
126
119
 
127
120
  /**
128
121
  * @typedef {{
129
122
  * inputType: string
130
123
  * outputType: string
131
- * internalType: TypeSchema
124
+ * internalType: TypeSchema16
132
125
  * }} TypeDetails
133
126
  */
134
127
 
@@ -183,7 +176,9 @@ export class CompilerLib_v0_16 {
183
176
  case "staking":
184
177
  return this.lib.StakingValidatorHashType
185
178
  default:
186
- throw new Error("unhandled validator type")
179
+ throw new Error(
180
+ `Helios v${this.version} doesn't support validator purpose '${purpose}' (hint: supported purposes are 'spending', 'minting' and 'staking')`
181
+ )
187
182
  }
188
183
  }
189
184
 
@@ -207,16 +202,15 @@ export class CompilerLib_v0_16 {
207
202
  }
208
203
  )
209
204
 
210
- if (options.parameters && Object.keys(options.parameters).length > 0) {
211
- program.parameters = options.parameters
212
- }
205
+ this.setParameters(program, options.parameters)
213
206
 
214
- const extra = this.generateExtraIRDefinitions(
207
+ const extra = this.genExtraIRDefs(
215
208
  name,
216
209
  purpose,
217
210
  program.nPosParams,
218
211
  options
219
212
  )
213
+
220
214
  const optimize = options.optimize
221
215
  const ir = program.toIR(new this.lib.ToIRContext(optimize), extra)
222
216
 
@@ -233,7 +227,6 @@ export class CompilerLib_v0_16 {
233
227
  const cborHex = bytesToHex(irProgram.toUplc().toCbor())
234
228
 
235
229
  return {
236
- prettyIR: irProgram.program.annotate(),
237
230
  cborHex
238
231
  }
239
232
  }
@@ -244,12 +237,7 @@ export class CompilerLib_v0_16 {
244
237
  * @returns {TypeCheckOutput}
245
238
  */
246
239
  typeCheck(validators, modules) {
247
- const validatorTypes = Object.fromEntries(
248
- validators.map((v) => {
249
- const [purpose, name] = readHeader(v)
250
- return [name, this.getScriptHashType(purpose)]
251
- })
252
- )
240
+ const validatorTypes = getValidatorTypes(this, validators)
253
241
 
254
242
  // create validator programs
255
243
  let validatorPrograms = this.createPrograms(
@@ -353,7 +341,7 @@ export class CompilerLib_v0_16 {
353
341
  * @param {CompileOptions} options
354
342
  * @returns {Map<string, IR>}
355
343
  */
356
- generateExtraIRDefinitions(name, purpose, nPosParams, options) {
344
+ genExtraIRDefs(name, purpose, nPosParams, options) {
357
345
  /**
358
346
  * @type {Map<string, IR>}
359
347
  */
@@ -467,30 +455,47 @@ export class CompilerLib_v0_16 {
467
455
 
468
456
  /**
469
457
  * @private
470
- * @param {TypeSchema} it
471
- * @returns {InternalTypeDetails}
458
+ * @param {TypeSchema16} it
459
+ * @returns {TypeSchema}
472
460
  */
473
461
  convertInternalType(it) {
474
462
  if ("itemType" in it) {
475
- return { listItemType: this.convertInternalType(it.itemType) }
463
+ return {
464
+ kind: "list",
465
+ itemType: this.convertInternalType(it.itemType)
466
+ }
476
467
  } else if ("someType" in it) {
477
- return { optionSomeType: this.convertInternalType(it.someType) }
468
+ return {
469
+ kind: "option",
470
+ someType: this.convertInternalType(it.someType)
471
+ }
478
472
  } else if ("fieldTypes" in it) {
479
473
  return {
480
- structFieldTypes: it.fieldTypes.map((ft) => ({
474
+ kind: "struct",
475
+ id: "",
476
+ name: "",
477
+ format: it.fieldTypes.length == 1 ? "singleton" : "list",
478
+ fieldTypes: it.fieldTypes.map((ft) => ({
481
479
  name: ft.name,
482
480
  type: this.convertInternalType(ft)
483
481
  }))
484
482
  }
485
483
  } else if ("keyType" in it) {
486
484
  return {
487
- mapKeyType: this.convertInternalType(it.keyType),
488
- mapValueType: this.convertInternalType(it.valueType)
485
+ kind: "map",
486
+ keyType: this.convertInternalType(it.keyType),
487
+ valueType: this.convertInternalType(it.valueType)
489
488
  }
490
489
  } else if ("variantTypes" in it) {
491
490
  return {
492
- enumVariantTypes: it.variantTypes.map((vt) => ({
491
+ kind: "enum",
492
+ id: "",
493
+ name: "",
494
+ variantTypes: it.variantTypes.map((vt, i) => ({
495
+ kind: "variant",
493
496
  name: vt.name,
497
+ tag: i,
498
+ id: "",
494
499
  fieldTypes: vt.fieldTypes.map((ft) => ({
495
500
  name: ft.name,
496
501
  type: this.convertInternalType(ft)
@@ -498,7 +503,7 @@ export class CompilerLib_v0_16 {
498
503
  }))
499
504
  }
500
505
  } else {
501
- return { primitiveType: it.type }
506
+ return { kind: "internal", name: it.type }
502
507
  }
503
508
  }
504
509
 
@@ -507,7 +512,7 @@ export class CompilerLib_v0_16 {
507
512
  * TODO: make sure it works for all structs and enums
508
513
  * @private
509
514
  * @param {DataType} dt
510
- * @returns {InternalTypeDetails}
515
+ * @returns {TypeSchema}
511
516
  */
512
517
  getInternalTypeDetails(dt) {
513
518
  try {
@@ -516,17 +521,17 @@ export class CompilerLib_v0_16 {
516
521
  return this.convertInternalType(it)
517
522
  } catch (e) {
518
523
  if (e.message.includes("Data")) {
519
- return { primitiveType: "Data" }
524
+ return { kind: "internal", name: "Data" }
520
525
  } else if (e.message.includes("DCert")) {
521
- return { primitiveType: "DCert" }
526
+ return { kind: "internal", name: "DCert" }
522
527
  } else if (e.message.includes("Credential")) {
523
- return { primitiveType: "SpendingCredential" }
528
+ return { kind: "internal", name: "SpendingCredential" }
524
529
  } else if (e.message.includes("OutputDatum")) {
525
- return { primitiveType: "TxOutputDatum" }
530
+ return { kind: "internal", name: "TxOutputDatum" }
526
531
  } else if (e.message.includes("PubKey")) {
527
- return { primitiveType: "PubKey" }
532
+ return { kind: "internal", name: "PubKey" }
528
533
  } else if (e.message.includes("ScriptHash")) {
529
- return { primitiveType: "ScriptHash" }
534
+ return { kind: "internal", name: "ScriptHash" }
530
535
  } else {
531
536
  throw e
532
537
  }
@@ -586,4 +591,23 @@ export class CompilerLib_v0_16 {
586
591
 
587
592
  return result
588
593
  }
594
+
595
+ /**
596
+ * @private
597
+ * @param {any} program
598
+ * @param {Option<Record<string, UplcData>>} parameters
599
+ */
600
+ setParameters(program, parameters) {
601
+ if (!parameters) {
602
+ return
603
+ }
604
+
605
+ const paramTypes = program.paramTypes
606
+
607
+ Object.entries(parameters).forEach(([key, value]) => {
608
+ if (key in paramTypes) {
609
+ program.changeParamSafe(key, value)
610
+ }
611
+ })
612
+ }
589
613
  }