@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,293 @@
|
|
|
1
|
+
import { decodeUtf8, encodeUtf8 } from "@helios-lang/codec-utils"
|
|
2
|
+
import { REAL_PRECISION } from "@helios-lang/compiler-utils"
|
|
3
|
+
import { None } from "@helios-lang/type-utils"
|
|
4
|
+
import {
|
|
5
|
+
Address,
|
|
6
|
+
AssetClass,
|
|
7
|
+
Credential,
|
|
8
|
+
DatumHash,
|
|
9
|
+
DCert,
|
|
10
|
+
MintingPolicyHash,
|
|
11
|
+
PubKeyHash,
|
|
12
|
+
ScriptHash,
|
|
13
|
+
StakingCredential,
|
|
14
|
+
StakingHash,
|
|
15
|
+
StakingValidatorHash,
|
|
16
|
+
TimeRange,
|
|
17
|
+
TxId,
|
|
18
|
+
TxOutputDatum,
|
|
19
|
+
TxOutputId,
|
|
20
|
+
ValidatorHash,
|
|
21
|
+
Value
|
|
22
|
+
} from "@helios-lang/ledger"
|
|
23
|
+
import {
|
|
24
|
+
ByteArrayData,
|
|
25
|
+
ConstrData,
|
|
26
|
+
IntData,
|
|
27
|
+
ListData,
|
|
28
|
+
MapData,
|
|
29
|
+
decodeOptionData,
|
|
30
|
+
encodeOptionData
|
|
31
|
+
} from "@helios-lang/uplc"
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @typedef {import("@helios-lang/uplc").UplcData} UplcData
|
|
35
|
+
* @typedef {import("../codegen/index.js").TypeSchema} TypeSchema
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @template TStrict
|
|
40
|
+
* @template TPermissive
|
|
41
|
+
*/
|
|
42
|
+
export class Cast {
|
|
43
|
+
/**
|
|
44
|
+
* @readonly
|
|
45
|
+
* @type {TypeSchema}
|
|
46
|
+
*/
|
|
47
|
+
schema
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @param {TypeSchema} schema
|
|
51
|
+
*/
|
|
52
|
+
constructor(schema) {
|
|
53
|
+
this.schema = schema
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {UplcData} data
|
|
58
|
+
* @returns {TStrict}
|
|
59
|
+
*/
|
|
60
|
+
fromUplc(data) {
|
|
61
|
+
return uplcToSchema(this.schema, data)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @param {TPermissive} x
|
|
66
|
+
* @returns {UplcData}
|
|
67
|
+
*/
|
|
68
|
+
toUplc(x) {
|
|
69
|
+
return schemaToUplc(this.schema, x)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @param {TypeSchema} schema
|
|
75
|
+
* @param {any} x
|
|
76
|
+
* @returns {UplcData}
|
|
77
|
+
*/
|
|
78
|
+
function schemaToUplc(schema, x) {
|
|
79
|
+
if ("primitiveType" in schema) {
|
|
80
|
+
switch (schema.primitiveType) {
|
|
81
|
+
case "Address":
|
|
82
|
+
return Address.fromAlike(x).toUplcData()
|
|
83
|
+
case "Any":
|
|
84
|
+
return new IntData(0n)
|
|
85
|
+
case "AssetClass":
|
|
86
|
+
return AssetClass.fromAlike(x).toUplcData()
|
|
87
|
+
case "Bool":
|
|
88
|
+
return new ConstrData(x ? 1 : 0, [])
|
|
89
|
+
case "ByteArray":
|
|
90
|
+
return new ByteArrayData(x)
|
|
91
|
+
case "Credential":
|
|
92
|
+
case "PaymentCredential":
|
|
93
|
+
return Credential.fromAlike(x).toUplcData()
|
|
94
|
+
case "Data":
|
|
95
|
+
return x
|
|
96
|
+
case "DatumHash":
|
|
97
|
+
return DatumHash.fromAlike(x).toUplcData()
|
|
98
|
+
case "DCert":
|
|
99
|
+
return x.toUplcData()
|
|
100
|
+
case "MintingPolicyHash":
|
|
101
|
+
return MintingPolicyHash.fromAlike(x).toUplcData()
|
|
102
|
+
case "PubKeyHash":
|
|
103
|
+
return PubKeyHash.fromAlike(x).toUplcData()
|
|
104
|
+
case "Real":
|
|
105
|
+
return new IntData(Math.round(x * Math.pow(10, REAL_PRECISION)))
|
|
106
|
+
case "ScriptHash":
|
|
107
|
+
return ScriptHash.fromAlike(x).toUplcData()
|
|
108
|
+
case "StakingCredential":
|
|
109
|
+
return StakingCredential.fromAlike(x).toUplcData()
|
|
110
|
+
case "StakingHash":
|
|
111
|
+
return StakingHash.fromAlike(x).toUplcData()
|
|
112
|
+
case "String":
|
|
113
|
+
return new ByteArrayData(encodeUtf8(x))
|
|
114
|
+
case "Time":
|
|
115
|
+
// milliseconds since 1 jan 1970
|
|
116
|
+
const ms = x instanceof Date ? x.getTime() : x
|
|
117
|
+
return new IntData(ms)
|
|
118
|
+
case "TimeRange":
|
|
119
|
+
return TimeRange.fromAlike(x).toUplcData()
|
|
120
|
+
case "TxId":
|
|
121
|
+
return TxId.fromAlike(x).toUplcData()
|
|
122
|
+
case "TxOutputDatum":
|
|
123
|
+
return x
|
|
124
|
+
? TxOutputDatum.fromAlike(x)?.toUplcData() ??
|
|
125
|
+
new ConstrData(0, [])
|
|
126
|
+
: new ConstrData(0, [])
|
|
127
|
+
case "TxOutputId":
|
|
128
|
+
return TxOutputId.fromAlike(x).toUplcData()
|
|
129
|
+
case "ValidatorHash":
|
|
130
|
+
return ValidatorHash.fromAlike(x).toUplcData()
|
|
131
|
+
case "Value":
|
|
132
|
+
return Value.fromAlike(x).toUplcData()
|
|
133
|
+
default:
|
|
134
|
+
throw new Error("not yet implemented")
|
|
135
|
+
}
|
|
136
|
+
} else if ("listItemType" in schema) {
|
|
137
|
+
return new ListData(x.map((x) => schemaToUplc(schema.listItemType, x)))
|
|
138
|
+
} else if ("mapKeyType" in schema) {
|
|
139
|
+
const entries = x instanceof Map ? x.entries() : x
|
|
140
|
+
return new MapData(
|
|
141
|
+
entries.map(([k, v]) => [
|
|
142
|
+
schemaToUplc(schema.mapKeyType, k),
|
|
143
|
+
schemaToUplc(schema.mapValueType, v)
|
|
144
|
+
])
|
|
145
|
+
)
|
|
146
|
+
} else if ("optionSomeType" in schema) {
|
|
147
|
+
return encodeOptionData(
|
|
148
|
+
x ? schemaToUplc(schema.optionSomeType, x) : None
|
|
149
|
+
)
|
|
150
|
+
} else if ("structFieldTypes" in schema) {
|
|
151
|
+
// TODO: Cip-68 support
|
|
152
|
+
if (schema.structFieldTypes.length == 1) {
|
|
153
|
+
return schemaToUplc(
|
|
154
|
+
schema.structFieldTypes[0].type,
|
|
155
|
+
x[schema.structFieldTypes[0].name]
|
|
156
|
+
)
|
|
157
|
+
} else {
|
|
158
|
+
return new ListData(
|
|
159
|
+
schema.structFieldTypes.map(({ name, type }) =>
|
|
160
|
+
schemaToUplc(type, x[name])
|
|
161
|
+
)
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
} else if ("enumVariantTypes") {
|
|
165
|
+
const variantName = Object.keys(x)[0]
|
|
166
|
+
const variantFields = Object.values(x)[0]
|
|
167
|
+
const tag = schema.enumVariantTypes.findIndex(
|
|
168
|
+
(v) => v.name == variantName
|
|
169
|
+
)
|
|
170
|
+
if (tag != -1) {
|
|
171
|
+
throw new Error("invalid variant")
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return new ConstrData(
|
|
175
|
+
tag,
|
|
176
|
+
schema.enumVariantTypes[tag].fieldTypes.map((f) =>
|
|
177
|
+
schemaToUplc(f.type, variantFields[f.name])
|
|
178
|
+
)
|
|
179
|
+
)
|
|
180
|
+
} else {
|
|
181
|
+
throw new Error("not yet implemented")
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* @param {TypeSchema} schema
|
|
187
|
+
* @param {UplcData} data
|
|
188
|
+
* @returns {any}
|
|
189
|
+
*/
|
|
190
|
+
function uplcToSchema(schema, data) {
|
|
191
|
+
if ("primitiveType" in schema) {
|
|
192
|
+
switch (schema.primitiveType) {
|
|
193
|
+
case "Address":
|
|
194
|
+
return Address.fromUplcData(data)
|
|
195
|
+
case "Any":
|
|
196
|
+
// TODO: should this throw an error?
|
|
197
|
+
return null
|
|
198
|
+
case "Bool":
|
|
199
|
+
return ConstrData.expect(data).tag == 1
|
|
200
|
+
case "ByteArray":
|
|
201
|
+
return ByteArrayData.expect(data).bytes
|
|
202
|
+
case "Credential":
|
|
203
|
+
return Credential.fromUplcData(data)
|
|
204
|
+
case "Data":
|
|
205
|
+
return data
|
|
206
|
+
case "DCert":
|
|
207
|
+
throw new Error(
|
|
208
|
+
"can't convert UplcData back into DCert (significant loss of information)"
|
|
209
|
+
)
|
|
210
|
+
case "MintingPolicyHash":
|
|
211
|
+
return MintingPolicyHash.fromUplcData(data)
|
|
212
|
+
case "PubKeyHash":
|
|
213
|
+
return PubKeyHash.fromUplcData(data)
|
|
214
|
+
case "Real":
|
|
215
|
+
return (
|
|
216
|
+
Number(IntData.expect(data).value) /
|
|
217
|
+
Math.pow(10, REAL_PRECISION)
|
|
218
|
+
)
|
|
219
|
+
case "ScriptHash":
|
|
220
|
+
return ScriptHash.fromUplcData(data)
|
|
221
|
+
case "StakingCredential":
|
|
222
|
+
return StakingCredential.fromUplcData(data)
|
|
223
|
+
case "StakingHash":
|
|
224
|
+
return StakingHash.fromUplcData(data)
|
|
225
|
+
case "StakingValidatorHash":
|
|
226
|
+
return StakingValidatorHash.fromUplcData(data)
|
|
227
|
+
case "String":
|
|
228
|
+
return decodeUtf8(ByteArrayData.expect(data).bytes)
|
|
229
|
+
case "Time":
|
|
230
|
+
return new Date(Number(IntData.expect(data).value))
|
|
231
|
+
case "TimeRange":
|
|
232
|
+
return TimeRange.fromUplcData(data)
|
|
233
|
+
case "TxId":
|
|
234
|
+
return TxId.fromUplcData(data)
|
|
235
|
+
case "TxOutputId":
|
|
236
|
+
return TxOutputId.fromUplcData(data)
|
|
237
|
+
case "ValidatorHash":
|
|
238
|
+
return ValidatorHash.fromUplcData(data)
|
|
239
|
+
case "Value":
|
|
240
|
+
return Value.fromUplcData(data)
|
|
241
|
+
default:
|
|
242
|
+
throw new Error("not yet implemented")
|
|
243
|
+
}
|
|
244
|
+
} else if ("listItemType" in schema) {
|
|
245
|
+
return ListData.expect(data).items.map((x) =>
|
|
246
|
+
uplcToSchema(schema.listItemType, x)
|
|
247
|
+
)
|
|
248
|
+
} else if ("mapKeyType" in schema) {
|
|
249
|
+
return new Map(
|
|
250
|
+
MapData.expect(data).items.map(([k, v]) => [
|
|
251
|
+
uplcToSchema(schema.mapKeyType, k),
|
|
252
|
+
uplcToSchema(schema.mapValueType, v)
|
|
253
|
+
])
|
|
254
|
+
)
|
|
255
|
+
} else if ("optionSomeType" in schema) {
|
|
256
|
+
const optionData = decodeOptionData(data)
|
|
257
|
+
return optionData
|
|
258
|
+
? uplcToSchema(schema.optionSomeType, optionData)
|
|
259
|
+
: None
|
|
260
|
+
} else if ("structFieldTypes" in schema) {
|
|
261
|
+
// TODO: Cip-68 support
|
|
262
|
+
if (schema.structFieldTypes.length == 1) {
|
|
263
|
+
return {
|
|
264
|
+
[schema.structFieldTypes[0].name]: uplcToSchema(
|
|
265
|
+
schema.structFieldTypes[0].type,
|
|
266
|
+
data
|
|
267
|
+
)
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
return Object.fromEntries(
|
|
271
|
+
ListData.expect(data).items.map((item, i) => [
|
|
272
|
+
schema.structFieldTypes[i].name,
|
|
273
|
+
uplcToSchema(schema.structFieldTypes[i].type, item)
|
|
274
|
+
])
|
|
275
|
+
)
|
|
276
|
+
}
|
|
277
|
+
} else if ("enumVariantTypes" in schema) {
|
|
278
|
+
const { tag, fields } = ConstrData.expect(data)
|
|
279
|
+
|
|
280
|
+
const variantSchema = schema.enumVariantTypes[tag]
|
|
281
|
+
|
|
282
|
+
return {
|
|
283
|
+
[variantSchema.name]: Object.fromEntries(
|
|
284
|
+
fields.map((f, i) => [
|
|
285
|
+
variantSchema.fieldTypes[i].name,
|
|
286
|
+
uplcToSchema(variantSchema.fieldTypes[i].type, f)
|
|
287
|
+
])
|
|
288
|
+
)
|
|
289
|
+
}
|
|
290
|
+
} else {
|
|
291
|
+
throw new Error("not yet implemented")
|
|
292
|
+
}
|
|
293
|
+
}
|
package/.prettierignore
DELETED