@helios-lang/contract-utils 0.2.9 → 0.2.11
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/package.json +2 -2
- package/src/cast/Cast.js +323 -219
- package/src/codegen/TypeSchema.js +141 -143
- package/src/compiler/CompilerLib.js +29 -4
- package/src/compiler/CompilerLib_v0_16.js +75 -51
- package/src/compiler/CompilerLib_v0_17.js +107 -0
- package/src/compiler/ops.js +5 -0
- package/src/context/ContractContextBuilder.js +1 -0
- package/src/context/DagCompiler.js +9 -8
- package/src/hl2ts.js +1 -1
- package/types/cast/Cast.d.ts.map +1 -1
- package/types/codegen/TypeCheckedModule.d.ts +1 -1
- package/types/codegen/TypeSchema.d.ts +3 -56
- package/types/codegen/TypeSchema.d.ts.map +1 -1
- package/types/compiler/CompilerLib.d.ts +66 -3
- package/types/compiler/CompilerLib.d.ts.map +1 -1
- package/types/compiler/CompilerLib_v0_16.d.ts +38 -39
- package/types/compiler/CompilerLib_v0_16.d.ts.map +1 -1
- package/types/compiler/CompilerLib_v0_17.d.ts +68 -0
- package/types/compiler/CompilerLib_v0_17.d.ts.map +1 -0
- package/types/compiler/ops.d.ts.map +1 -1
- package/types/context/ContractContextBuilder.d.ts.map +1 -1
- package/types/context/ContractContextCache.d.ts +1 -1
- package/types/context/DagCompiler.d.ts +2 -1
- package/types/context/DagCompiler.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helios-lang/contract-utils",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.11",
|
|
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",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@helios-lang/codec-utils": "^0.1.30",
|
|
40
40
|
"@helios-lang/compiler-utils": "^0.1.25",
|
|
41
41
|
"@helios-lang/ledger": "^0.2.7",
|
|
42
|
-
"@helios-lang/type-utils": "^0.1.
|
|
42
|
+
"@helios-lang/type-utils": "^0.1.20",
|
|
43
43
|
"@helios-lang/uplc": "^0.1.31"
|
|
44
44
|
}
|
|
45
45
|
}
|
package/src/cast/Cast.js
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
ValidatorHash,
|
|
18
18
|
Value
|
|
19
19
|
} from "@helios-lang/ledger"
|
|
20
|
-
import { None } from "@helios-lang/type-utils"
|
|
20
|
+
import { None, expectSome } from "@helios-lang/type-utils"
|
|
21
21
|
import {
|
|
22
22
|
ByteArrayData,
|
|
23
23
|
ConstrData,
|
|
@@ -102,120 +102,156 @@ export class Cast {
|
|
|
102
102
|
/**
|
|
103
103
|
* @param {TypeSchema} schema
|
|
104
104
|
* @param {any} x
|
|
105
|
+
* @param {Record<string, TypeSchema>} defs
|
|
105
106
|
* @returns {UplcData}
|
|
106
107
|
*/
|
|
107
|
-
function schemaToUplc(schema, x) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
case "AssetClass":
|
|
115
|
-
return AssetClass.new(x).toUplcData()
|
|
116
|
-
case "Bool":
|
|
117
|
-
return encodeBoolData(x)
|
|
118
|
-
case "ByteArray":
|
|
119
|
-
return new ByteArrayData(x)
|
|
120
|
-
case "Credential":
|
|
121
|
-
case "PaymentCredential":
|
|
122
|
-
return SpendingCredential.new(x).toUplcData()
|
|
123
|
-
case "Data":
|
|
124
|
-
return x
|
|
125
|
-
case "DatumHash":
|
|
126
|
-
return DatumHash.new(x).toUplcData()
|
|
127
|
-
case "DCert":
|
|
128
|
-
return x.toUplcData()
|
|
129
|
-
case "Duration":
|
|
130
|
-
case "Int":
|
|
131
|
-
return new IntData(x)
|
|
132
|
-
case "MintingPolicyHash":
|
|
133
|
-
return MintingPolicyHash.new(x).toUplcData()
|
|
134
|
-
case "PubKeyHash":
|
|
135
|
-
return PubKeyHash.new(x).toUplcData()
|
|
136
|
-
case "Real":
|
|
137
|
-
return encodeRealData(x)
|
|
138
|
-
case "ScriptHash":
|
|
139
|
-
return ScriptHash.new(x).toUplcData()
|
|
140
|
-
case "StakingCredential":
|
|
141
|
-
return StakingCredential.new(x).toUplcData()
|
|
142
|
-
case "StakingHash":
|
|
143
|
-
return StakingHash.new(x).toUplcData()
|
|
144
|
-
case "String":
|
|
145
|
-
return new ByteArrayData(encodeUtf8(x))
|
|
146
|
-
case "Time":
|
|
147
|
-
return new IntData(x)
|
|
148
|
-
case "TimeRange":
|
|
149
|
-
return TimeRange.new(x).toUplcData()
|
|
150
|
-
case "TxId":
|
|
151
|
-
return TxId.new(x).toUplcData()
|
|
152
|
-
case "TxOutputDatum":
|
|
153
|
-
return x
|
|
154
|
-
? TxOutputDatum.new(x)?.toUplcData() ??
|
|
155
|
-
new ConstrData(0, [])
|
|
156
|
-
: new ConstrData(0, [])
|
|
157
|
-
case "TxOutputId":
|
|
158
|
-
return TxOutputId.new(x).toUplcData()
|
|
159
|
-
case "ValidatorHash":
|
|
160
|
-
return ValidatorHash.new(x).toUplcData()
|
|
161
|
-
case "Value":
|
|
162
|
-
return Value.new(x).toUplcData()
|
|
163
|
-
default:
|
|
164
|
-
throw new Error(
|
|
165
|
-
`not yet implemented for ${schema.primitiveType}`
|
|
166
|
-
)
|
|
108
|
+
function schemaToUplc(schema, x, defs = {}) {
|
|
109
|
+
const kind = schema.kind
|
|
110
|
+
|
|
111
|
+
switch (kind) {
|
|
112
|
+
case "reference": {
|
|
113
|
+
const def = expectSome(defs[schema.id])
|
|
114
|
+
return schemaToUplc(def, x, defs)
|
|
167
115
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
116
|
+
case "internal": {
|
|
117
|
+
const name = schema.name
|
|
118
|
+
|
|
119
|
+
switch (name) {
|
|
120
|
+
case "Address":
|
|
121
|
+
return Address.new(x).toUplcData()
|
|
122
|
+
case "Any":
|
|
123
|
+
return new IntData(0n)
|
|
124
|
+
case "AssetClass":
|
|
125
|
+
return AssetClass.new(x).toUplcData()
|
|
126
|
+
case "Bool":
|
|
127
|
+
return encodeBoolData(x)
|
|
128
|
+
case "ByteArray":
|
|
129
|
+
return new ByteArrayData(x)
|
|
130
|
+
case "Credential":
|
|
131
|
+
case "SpendingCredential":
|
|
132
|
+
return SpendingCredential.new(x).toUplcData()
|
|
133
|
+
case "Data":
|
|
134
|
+
return x
|
|
135
|
+
case "DatumHash":
|
|
136
|
+
return DatumHash.new(x).toUplcData()
|
|
137
|
+
case "DCert":
|
|
138
|
+
return x.toUplcData()
|
|
139
|
+
case "Duration":
|
|
140
|
+
case "Int":
|
|
141
|
+
return new IntData(x)
|
|
142
|
+
case "MintingPolicyHash":
|
|
143
|
+
return MintingPolicyHash.new(x).toUplcData()
|
|
144
|
+
case "PubKeyHash":
|
|
145
|
+
return PubKeyHash.new(x).toUplcData()
|
|
146
|
+
case "Real":
|
|
147
|
+
return encodeRealData(x)
|
|
148
|
+
case "Ratio":
|
|
149
|
+
return new ListData([new IntData(x[0]), new IntData(x[1])])
|
|
150
|
+
case "ScriptHash":
|
|
151
|
+
return ScriptHash.new(x).toUplcData()
|
|
152
|
+
case "StakingCredential":
|
|
153
|
+
return StakingCredential.new(x).toUplcData()
|
|
154
|
+
case "StakingHash":
|
|
155
|
+
return StakingHash.new(x).toUplcData()
|
|
156
|
+
case "String":
|
|
157
|
+
return new ByteArrayData(encodeUtf8(x))
|
|
158
|
+
case "Time":
|
|
159
|
+
return new IntData(x)
|
|
160
|
+
case "TimeRange":
|
|
161
|
+
return TimeRange.new(x).toUplcData()
|
|
162
|
+
case "TxId":
|
|
163
|
+
return TxId.new(x).toUplcData()
|
|
164
|
+
case "TxOutputDatum":
|
|
165
|
+
return x
|
|
166
|
+
? TxOutputDatum.new(x)?.toUplcData() ??
|
|
167
|
+
new ConstrData(0, [])
|
|
168
|
+
: new ConstrData(0, [])
|
|
169
|
+
case "TxOutputId":
|
|
170
|
+
return TxOutputId.new(x).toUplcData()
|
|
171
|
+
case "ValidatorHash":
|
|
172
|
+
return ValidatorHash.new(x).toUplcData()
|
|
173
|
+
case "Value":
|
|
174
|
+
return Value.new(x).toUplcData()
|
|
175
|
+
default:
|
|
176
|
+
throw new Error(`not yet implemented for ${name}`)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
case "list":
|
|
190
180
|
return new ListData(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
181
|
+
x.map((x) => schemaToUplc(schema.itemType, x, defs))
|
|
182
|
+
)
|
|
183
|
+
case "map": {
|
|
184
|
+
const entries = x instanceof Map ? x.entries() : x
|
|
185
|
+
return new MapData(
|
|
186
|
+
entries.map(([k, v]) => [
|
|
187
|
+
schemaToUplc(schema.keyType, k, defs),
|
|
188
|
+
schemaToUplc(schema.valueType, v, defs)
|
|
189
|
+
])
|
|
194
190
|
)
|
|
195
191
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const tag = schema.enumVariantTypes.findIndex(
|
|
200
|
-
(v) => v.name == variantName
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
if (tag == -1) {
|
|
204
|
-
throw new Error(
|
|
205
|
-
`invalid variant ${variantName} (expected: ${schema.enumVariantTypes.map((v) => v.name).join(", ")})`
|
|
192
|
+
case "option":
|
|
193
|
+
return encodeOptionData(
|
|
194
|
+
x ? schemaToUplc(schema.someType, x, defs) : None
|
|
206
195
|
)
|
|
196
|
+
case "struct": {
|
|
197
|
+
defs[schema.id] = schema
|
|
198
|
+
switch (schema.format) {
|
|
199
|
+
case "singleton":
|
|
200
|
+
return schemaToUplc(
|
|
201
|
+
schema.fieldTypes[0].type,
|
|
202
|
+
x[schema.fieldTypes[0].name],
|
|
203
|
+
defs
|
|
204
|
+
)
|
|
205
|
+
case "list":
|
|
206
|
+
return new ListData(
|
|
207
|
+
schema.fieldTypes.map(({ name, type }) =>
|
|
208
|
+
schemaToUplc(type, x[name])
|
|
209
|
+
)
|
|
210
|
+
)
|
|
211
|
+
case "map":
|
|
212
|
+
return new MapData(
|
|
213
|
+
schema.fieldTypes.map(({ name, type }) => [
|
|
214
|
+
new ByteArrayData(encodeUtf8(name)),
|
|
215
|
+
schemaToUplc(type, x[name], defs)
|
|
216
|
+
])
|
|
217
|
+
)
|
|
218
|
+
default:
|
|
219
|
+
throw new Error(
|
|
220
|
+
`unhandled struct format '${schema.format}'`
|
|
221
|
+
)
|
|
222
|
+
}
|
|
207
223
|
}
|
|
224
|
+
case "enum": {
|
|
225
|
+
defs[schema.id] = schema
|
|
226
|
+
const variantName = Object.keys(x)[0]
|
|
227
|
+
const variantFields = Object.values(x)[0]
|
|
228
|
+
const tag = schema.variantTypes.findIndex(
|
|
229
|
+
(v) => v.name == variantName
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
if (tag == -1) {
|
|
233
|
+
throw new Error(
|
|
234
|
+
`invalid variant ${variantName} (expected: ${schema.variantTypes.map((v) => v.name).join(", ")})`
|
|
235
|
+
)
|
|
236
|
+
}
|
|
208
237
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
238
|
+
return new ConstrData(
|
|
239
|
+
tag,
|
|
240
|
+
schema.variantTypes[tag].fieldTypes.map((f) =>
|
|
241
|
+
schemaToUplc(f.type, variantFields[f.name], defs)
|
|
242
|
+
)
|
|
213
243
|
)
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
244
|
+
}
|
|
245
|
+
case "variant":
|
|
246
|
+
defs[schema.id] = schema
|
|
247
|
+
return new ConstrData(
|
|
248
|
+
schema.tag,
|
|
249
|
+
schema.fieldTypes.map(({ name, type }) =>
|
|
250
|
+
schemaToUplc(type, x[name])
|
|
251
|
+
)
|
|
252
|
+
)
|
|
253
|
+
default:
|
|
254
|
+
throw new Error(`unhandled schema kind '${kind}'`)
|
|
219
255
|
}
|
|
220
256
|
}
|
|
221
257
|
|
|
@@ -224,137 +260,205 @@ function schemaToUplc(schema, x) {
|
|
|
224
260
|
* @param {TypeSchema} schema
|
|
225
261
|
* @param {UplcData} data
|
|
226
262
|
* @param {CastConfig} config
|
|
263
|
+
* @param {Record<string, TypeSchema>} defs
|
|
227
264
|
* @returns {any}
|
|
228
265
|
*/
|
|
229
|
-
function uplcToSchema(schema, data, config) {
|
|
230
|
-
|
|
231
|
-
switch (schema.primitiveType) {
|
|
232
|
-
case "Address":
|
|
233
|
-
return Address.fromUplcData(config.isMainnet, data)
|
|
234
|
-
case "Any":
|
|
235
|
-
// TODO: should this throw an error?
|
|
236
|
-
return null
|
|
237
|
-
case "Bool":
|
|
238
|
-
return decodeBoolData(data, true)
|
|
239
|
-
case "ByteArray":
|
|
240
|
-
return ByteArrayData.expect(data).bytes
|
|
241
|
-
case "SpendingCredential":
|
|
242
|
-
case "Credential":
|
|
243
|
-
return SpendingCredential.fromUplcData(data)
|
|
244
|
-
case "Data":
|
|
245
|
-
return data
|
|
246
|
-
case "DCert":
|
|
247
|
-
throw new Error(
|
|
248
|
-
"can't convert UplcData back into DCert (significant loss of information)"
|
|
249
|
-
)
|
|
250
|
-
case "Duration":
|
|
251
|
-
case "Int":
|
|
252
|
-
return IntData.expect(data).value
|
|
253
|
-
case "MintingPolicyHash":
|
|
254
|
-
return MintingPolicyHash.fromUplcData(data)
|
|
255
|
-
case "PubKeyHash":
|
|
256
|
-
return PubKeyHash.fromUplcData(data)
|
|
257
|
-
case "Real":
|
|
258
|
-
return decodeRealData(data)
|
|
259
|
-
case "ScriptHash":
|
|
260
|
-
return ScriptHash.fromUplcData(data)
|
|
261
|
-
case "StakingCredential":
|
|
262
|
-
return StakingCredential.fromUplcData(data)
|
|
263
|
-
case "StakingHash":
|
|
264
|
-
return StakingHash.fromUplcData(data)
|
|
265
|
-
case "StakingValidatorHash":
|
|
266
|
-
return StakingValidatorHash.fromUplcData(data)
|
|
267
|
-
case "String":
|
|
268
|
-
return decodeUtf8(ByteArrayData.expect(data).bytes)
|
|
269
|
-
case "Time":
|
|
270
|
-
return Number(IntData.expect(data).value) // a number has enough precision to represent ms since 1970 for another 142000 years
|
|
271
|
-
case "TimeRange":
|
|
272
|
-
return TimeRange.fromUplcData(data)
|
|
273
|
-
case "TxId":
|
|
274
|
-
return TxId.fromUplcData(data)
|
|
275
|
-
case "TxOutputId":
|
|
276
|
-
return TxOutputId.fromUplcData(data)
|
|
277
|
-
case "ValidatorHash":
|
|
278
|
-
return ValidatorHash.fromUplcData(data)
|
|
279
|
-
case "Value":
|
|
280
|
-
return Value.fromUplcData(data)
|
|
281
|
-
default:
|
|
282
|
-
throw new Error(
|
|
283
|
-
`not yet implemented for ${schema.primitiveType}`
|
|
284
|
-
)
|
|
285
|
-
}
|
|
286
|
-
} else if ("listItemType" in schema) {
|
|
287
|
-
return ListData.expect(data).items.map((x) =>
|
|
288
|
-
uplcToSchema(schema.listItemType, x, config)
|
|
289
|
-
)
|
|
290
|
-
} else if ("mapKeyType" in schema) {
|
|
291
|
-
return new Map(
|
|
292
|
-
MapData.expect(data).items.map(([k, v]) => [
|
|
293
|
-
uplcToSchema(schema.mapKeyType, k, config),
|
|
294
|
-
uplcToSchema(schema.mapValueType, v, config)
|
|
295
|
-
])
|
|
296
|
-
)
|
|
297
|
-
} else if ("optionSomeType" in schema) {
|
|
298
|
-
const optionData = decodeOptionData(data)
|
|
299
|
-
return optionData
|
|
300
|
-
? uplcToSchema(schema.optionSomeType, optionData, config)
|
|
301
|
-
: None
|
|
302
|
-
} else if ("structFieldTypes" in schema) {
|
|
303
|
-
const nExpected = schema.structFieldTypes.length
|
|
304
|
-
// TODO: Cip-68 support
|
|
305
|
-
if (nExpected == 1) {
|
|
306
|
-
return {
|
|
307
|
-
[schema.structFieldTypes[0].name]: uplcToSchema(
|
|
308
|
-
schema.structFieldTypes[0].type,
|
|
309
|
-
data,
|
|
310
|
-
config
|
|
311
|
-
)
|
|
312
|
-
}
|
|
313
|
-
} else {
|
|
314
|
-
const fields = ListData.expect(data).items
|
|
266
|
+
function uplcToSchema(schema, data, config, defs = {}) {
|
|
267
|
+
const kind = schema.kind
|
|
315
268
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
)
|
|
320
|
-
}
|
|
269
|
+
switch (kind) {
|
|
270
|
+
case "internal": {
|
|
271
|
+
const name = schema.name
|
|
321
272
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
273
|
+
switch (name) {
|
|
274
|
+
case "Address":
|
|
275
|
+
return Address.fromUplcData(config.isMainnet, data)
|
|
276
|
+
case "Any":
|
|
277
|
+
// TODO: should this throw an error?
|
|
278
|
+
return null
|
|
279
|
+
case "Bool":
|
|
280
|
+
return decodeBoolData(data, true)
|
|
281
|
+
case "ByteArray":
|
|
282
|
+
return ByteArrayData.expect(data).bytes
|
|
283
|
+
case "SpendingCredential":
|
|
284
|
+
case "Credential":
|
|
285
|
+
return SpendingCredential.fromUplcData(data)
|
|
286
|
+
case "Data":
|
|
287
|
+
return data
|
|
288
|
+
case "DCert":
|
|
289
|
+
throw new Error(
|
|
290
|
+
"can't convert UplcData back into DCert (significant loss of information)"
|
|
291
|
+
)
|
|
292
|
+
case "Duration":
|
|
293
|
+
case "Int":
|
|
294
|
+
return IntData.expect(data).value
|
|
295
|
+
case "MintingPolicyHash":
|
|
296
|
+
return MintingPolicyHash.fromUplcData(data)
|
|
297
|
+
case "PubKeyHash":
|
|
298
|
+
return PubKeyHash.fromUplcData(data)
|
|
299
|
+
case "Ratio": {
|
|
300
|
+
const [top, bottom] = ListData.expect(data).items
|
|
301
|
+
return [
|
|
302
|
+
IntData.expect(top).value,
|
|
303
|
+
IntData.expect(bottom).value
|
|
304
|
+
]
|
|
305
|
+
}
|
|
306
|
+
case "Real":
|
|
307
|
+
return decodeRealData(data)
|
|
308
|
+
case "ScriptHash":
|
|
309
|
+
return ScriptHash.fromUplcData(data)
|
|
310
|
+
case "StakingCredential":
|
|
311
|
+
return StakingCredential.fromUplcData(data)
|
|
312
|
+
case "StakingHash":
|
|
313
|
+
return StakingHash.fromUplcData(data)
|
|
314
|
+
case "StakingValidatorHash":
|
|
315
|
+
return StakingValidatorHash.fromUplcData(data)
|
|
316
|
+
case "String":
|
|
317
|
+
return decodeUtf8(ByteArrayData.expect(data).bytes)
|
|
318
|
+
case "Time":
|
|
319
|
+
return Number(IntData.expect(data).value) // a number has enough precision to represent ms since 1970 for another 142000 years
|
|
320
|
+
case "TimeRange":
|
|
321
|
+
return TimeRange.fromUplcData(data)
|
|
322
|
+
case "TxId":
|
|
323
|
+
return TxId.fromUplcData(data)
|
|
324
|
+
case "TxOutputId":
|
|
325
|
+
return TxOutputId.fromUplcData(data)
|
|
326
|
+
case "ValidatorHash":
|
|
327
|
+
return ValidatorHash.fromUplcData(data)
|
|
328
|
+
case "Value":
|
|
329
|
+
return Value.fromUplcData(data)
|
|
330
|
+
default:
|
|
331
|
+
throw new Error(`not yet implemented for ${name}`)
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
case "list":
|
|
335
|
+
return ListData.expect(data).items.map((x) =>
|
|
336
|
+
uplcToSchema(schema.itemType, x, config, defs)
|
|
337
|
+
)
|
|
338
|
+
case "map":
|
|
339
|
+
return new Map(
|
|
340
|
+
MapData.expect(data).items.map(([k, v]) => [
|
|
341
|
+
uplcToSchema(schema.keyType, k, config, defs),
|
|
342
|
+
uplcToSchema(schema.valueType, v, config, defs)
|
|
326
343
|
])
|
|
327
344
|
)
|
|
345
|
+
case "option": {
|
|
346
|
+
const optionData = decodeOptionData(data)
|
|
347
|
+
return optionData
|
|
348
|
+
? uplcToSchema(schema.someType, optionData, config, defs)
|
|
349
|
+
: None
|
|
328
350
|
}
|
|
329
|
-
|
|
330
|
-
|
|
351
|
+
case "struct": {
|
|
352
|
+
defs[schema.id] = schema
|
|
353
|
+
switch (schema.format) {
|
|
354
|
+
case "singleton":
|
|
355
|
+
return {
|
|
356
|
+
[schema.fieldTypes[0].name]: uplcToSchema(
|
|
357
|
+
schema.fieldTypes[0].type,
|
|
358
|
+
data,
|
|
359
|
+
config,
|
|
360
|
+
defs
|
|
361
|
+
)
|
|
362
|
+
}
|
|
363
|
+
case "list": {
|
|
364
|
+
const fields = ListData.expect(data).items
|
|
365
|
+
|
|
366
|
+
if (fields.length != schema.fieldTypes.length) {
|
|
367
|
+
throw new Error(
|
|
368
|
+
`expected ${schema.fieldTypes.length} fields in struct, got ${fields.length} fields`
|
|
369
|
+
)
|
|
370
|
+
}
|
|
331
371
|
|
|
332
|
-
|
|
372
|
+
return Object.fromEntries(
|
|
373
|
+
fields.map((field, i) => [
|
|
374
|
+
schema.fieldTypes[i].name,
|
|
375
|
+
uplcToSchema(
|
|
376
|
+
schema.fieldTypes[i].type,
|
|
377
|
+
field,
|
|
378
|
+
config,
|
|
379
|
+
defs
|
|
380
|
+
)
|
|
381
|
+
])
|
|
382
|
+
)
|
|
383
|
+
}
|
|
384
|
+
case "map": {
|
|
385
|
+
const entries = MapData.expect(data).items
|
|
333
386
|
|
|
334
|
-
|
|
335
|
-
|
|
387
|
+
if (entries.length != schema.fieldTypes.length) {
|
|
388
|
+
throw new Error(
|
|
389
|
+
`expected ${schema.fieldTypes.length} fields in struct, got ${entries.length} fields`
|
|
390
|
+
)
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return new Map(
|
|
394
|
+
schema.fieldTypes.map(({ name, type }) => {
|
|
395
|
+
const pair = expectSome(
|
|
396
|
+
entries.find(
|
|
397
|
+
([key, _]) =>
|
|
398
|
+
decodeUtf8(
|
|
399
|
+
ByteArrayData.expect(key).bytes
|
|
400
|
+
) == name
|
|
401
|
+
)
|
|
402
|
+
)
|
|
403
|
+
|
|
404
|
+
return [
|
|
405
|
+
name,
|
|
406
|
+
uplcToSchema(type, pair[1], config, defs)
|
|
407
|
+
]
|
|
408
|
+
})
|
|
409
|
+
)
|
|
410
|
+
}
|
|
411
|
+
default:
|
|
412
|
+
throw new Error(
|
|
413
|
+
`unhandled struct format '${schema.format}'`
|
|
414
|
+
)
|
|
415
|
+
}
|
|
336
416
|
}
|
|
417
|
+
case "enum": {
|
|
418
|
+
defs[schema.id] = schema
|
|
419
|
+
const { tag, fields } = ConstrData.expect(data)
|
|
337
420
|
|
|
338
|
-
|
|
421
|
+
const variantSchema = schema.variantTypes[tag]
|
|
339
422
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
423
|
+
if (!variantSchema) {
|
|
424
|
+
throw new Error(`tag ${tag} out of range`)
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
const nExpected = variantSchema.fieldTypes.length
|
|
428
|
+
|
|
429
|
+
if (fields.length != nExpected) {
|
|
430
|
+
throw new Error(
|
|
431
|
+
`expected ${nExpected} fields for variant ${variantSchema.name} (tag ${tag}), got ${fields.length} fields`
|
|
432
|
+
)
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return {
|
|
436
|
+
[variantSchema.name]: Object.fromEntries(
|
|
437
|
+
fields.map((f, i) => [
|
|
438
|
+
variantSchema.fieldTypes[i].name,
|
|
439
|
+
uplcToSchema(
|
|
440
|
+
variantSchema.fieldTypes[i].type,
|
|
441
|
+
f,
|
|
442
|
+
config,
|
|
443
|
+
defs
|
|
444
|
+
)
|
|
445
|
+
])
|
|
446
|
+
)
|
|
447
|
+
}
|
|
344
448
|
}
|
|
449
|
+
case "variant": {
|
|
450
|
+
defs[schema.id] = schema
|
|
451
|
+
const { fields } = ConstrData.expect(data)
|
|
345
452
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
uplcToSchema(variantSchema.fieldTypes[i].type, f, config)
|
|
453
|
+
return Object.fromEntries(
|
|
454
|
+
fields.map((field, i) => [
|
|
455
|
+
schema.fieldTypes[i].name,
|
|
456
|
+
uplcToSchema(schema.fieldTypes[i].type, field, config, defs)
|
|
351
457
|
])
|
|
352
458
|
)
|
|
353
459
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
`not yet implemented for ${JSON.stringify(schema, undefined, 4)}`
|
|
357
|
-
)
|
|
460
|
+
default:
|
|
461
|
+
throw new Error(`unhandled schema kind '${kind}'`)
|
|
358
462
|
}
|
|
359
463
|
}
|
|
360
464
|
|