Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@helios-lang/contract-utils

Package Overview
Dependencies
Maintainers
0
Versions
124
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@helios-lang/contract-utils - npm Package Compare versions

Comparing version 0.3.4 to 0.3.5

2

package.json
{
"name": "@helios-lang/contract-utils",
"version": "0.3.4",
"version": "0.3.5",
"description": "Convenience and type-safety utilities for using Helios validators from within Typescript",

@@ -5,0 +5,0 @@ "main": "src/index.js",

@@ -57,8 +57,23 @@ import { decodeUtf8, encodeUtf8 } from "@helios-lang/codec-utils"

* @import { TxInput, TxOutput } from "@helios-lang/ledger"
* @import { TypeSchema } from "@helios-lang/type-utils"
* @import { UplcData } from "@helios-lang/uplc"
* @import { Cast, CastConfig, CastLike, SchemaToUplcContext, UplcToSchemaContext } from "../index.js"
* @import { EnumTypeSchema, TypeSchema } from "@helios-lang/type-utils"
* @import { ConstrData, UplcData } from "@helios-lang/uplc"
* @import { Cast, CastConfig, CastLike } from "../index.js"
*/
/**
* @typedef {Object} SchemaToUplcContext
* @prop {Record<string, TypeSchema>} defs - symbol table permitting recursive schema references
* @prop {string} dataPath - provides developer-facing cues for any parsing errors, showing the deep field path of any error
* @prop {boolean} unwrapSingleFieldEnumVariants - defaults to false. If true, assumes the following input objects for enum variants: `{VariantName: SingleFieldData}`, instead of the more verbose `{VariantName: {SingleFieldName: SingleFieldData}}`
*/
/**
* @typedef {Object} UplcToSchemaContext
* @prop {Record<string, TypeSchema>} defs - symbol table permitting recursive schema references
* @prop {string} dataPath - provides developer-facing cues for any parsing errors, showing the deep field path of any error
* @prop {boolean} unwrapSingleFieldEnumVariants - defaults to false. If true, the following enum variant outputs are created: `{VariantName: SingleFieldData}`, instead of the more verbose `{VariantName: {SingleFieldName: SingleFieldData}}`
* @prop {boolean} isMainnet
*/
/**
* @template TStrict

@@ -114,4 +129,6 @@ * @template TPermissive=TStrict

fromUplcData(data, dataPath = "") {
return uplcToSchemaWithDataPath(this.schema, data, {
config: this.config,
return convertUplcDataToSchemaDataWithDataPath(this.schema, data, {
isMainnet: this.config.isMainnet,
unwrapSingleFieldEnumVariants:
!!this.config.unwrapSingleFieldEnumVariants,
dataPath,

@@ -134,4 +151,6 @@ defs: {}

toUplcData(x, dataPath = "") {
const t = schemaToUplcWithDataPath(this.schema, x, {
const t = convertSchemaDataToUplcDataWithDataPath(this.schema, x, {
defs: {},
unwrapSingleFieldEnumVariants:
!!this.config.unwrapSingleFieldEnumVariants,
dataPath

@@ -146,9 +165,9 @@ })

* @param {TypeSchema} schema
* @param {any} x
* @param {any} x - data
* @param {SchemaToUplcContext} context
* @returns {UplcData}
*/
function schemaToUplcWithDataPath(schema, x, context) {
function convertSchemaDataToUplcDataWithDataPath(schema, x, context) {
try {
const t = schemaToUplc(schema, x, context)
const t = convertSchemaDataToUplcData(schema, x, context)
t.dataPath = context.dataPath

@@ -167,15 +186,23 @@ return t

/**
* @template T [{dataPath: string}]
* @param {T} context
* @param {string} dataPath
* @returns {T}
*/
function passContext(context, dataPath) {
return {
...context,
dataPath
}
}
/**
* @param {TypeSchema} schema
* @param {any} x
* @param {SchemaToUplcContext} inputContextOnly
* @param {any} x - JS data
* @param {SchemaToUplcContext} context
* @returns {UplcData}
*/
function schemaToUplc(schema, x, inputContextOnly) {
// const { defs = {}, dataPath = "" } = inputContext
// important: DON'T extend the inputContext for use in nested calls.
const { dataPath, defs } = inputContextOnly
function convertSchemaDataToUplcData(schema, x, context) {
const { dataPath, defs } = context
// Only the defs can be passed down, and it's simpler syntactically
// ... just use the defs directly in the nested calls.
const kind = schema.kind

@@ -185,6 +212,7 @@ switch (kind) {

const def = expectDefined(defs[schema.id])
return schemaToUplcWithDataPath(def, x, {
defs,
dataPath: `${dataPath}::ref{${schema.id}}`
})
return convertSchemaDataToUplcDataWithDataPath(
def,
x,
passContext(context, `${dataPath}::ref{${schema.id}}`)
)
}

@@ -267,6 +295,7 @@ case "internal": {

x.map((x, i) =>
schemaToUplcWithDataPath(schema.itemType, x, {
defs,
dataPath: `${dataPath}.list[${i}]`
})
convertSchemaDataToUplcDataWithDataPath(
schema.itemType,
x,
passContext(context, `${dataPath}.list[${i}]`)
)
)

@@ -285,10 +314,18 @@ )

return [
schemaToUplcWithDataPath(schema.keyType, k, {
defs,
dataPath: `${dataPath}[mapKey ${displayKey}]`
}),
schemaToUplcWithDataPath(schema.valueType, v, {
defs,
dataPath: `${dataPath}[mapVal ${displayKey}]`
})
convertSchemaDataToUplcDataWithDataPath(
schema.keyType,
k,
passContext(
context,
`${dataPath}[mapKey ${displayKey}]`
)
),
convertSchemaDataToUplcDataWithDataPath(
schema.valueType,
v,
passContext(
context,
`${dataPath}[mapVal ${displayKey}]`
)
)
]

@@ -301,6 +338,7 @@ })

x.map((x, i) =>
schemaToUplcWithDataPath(schema.itemTypes[i], x, {
defs,
dataPath: `${dataPath}[tuple@${i}]`
})
convertSchemaDataToUplcDataWithDataPath(
schema.itemTypes[i],
x,
passContext(context, `${dataPath}[tuple@${i}]`)
)
)

@@ -311,6 +349,7 @@ )

x
? schemaToUplcWithDataPath(schema.someType, x, {
defs,
dataPath: `${dataPath}::Some`
})
? convertSchemaDataToUplcDataWithDataPath(
schema.someType,
x,
passContext(context, `${dataPath}::Some`)
)
: undefined

@@ -323,9 +362,9 @@ )

const singleFieldName = schema.fieldTypes[0].name
return schemaToUplcWithDataPath(
return convertSchemaDataToUplcDataWithDataPath(
schema.fieldTypes[0].type,
x[singleFieldName],
{
defs,
dataPath: `${dataPath}[sfStruct.${singleFieldName}]`
}
passContext(
context,
`${dataPath}[sfStruct.${singleFieldName}]`
)
)

@@ -335,6 +374,10 @@ case "list":

schema.fieldTypes.map(({ name, type }) =>
schemaToUplcWithDataPath(type, x[name], {
defs,
dataPath: `${dataPath}[fStruct].${name}`
})
convertSchemaDataToUplcDataWithDataPath(
type,
x[name],
passContext(
context,
`${dataPath}[fStruct].${name}`
)
)
)

@@ -380,10 +423,11 @@ )

const valueData = schemaToUplcWithDataPath(
ft.type,
value,
{
defs,
dataPath: `${dataPath}[mStruct].${fieldName}${encodingInfo}`
}
)
const valueData =
convertSchemaDataToUplcDataWithDataPath(
ft.type,
value,
passContext(
context,
`${dataPath}[mStruct].${fieldName}${encodingInfo}`
)
)

@@ -421,12 +465,7 @@ pairs.push([keyData, valueData])

// Gives the encoding of nested data a context to prevent a second ConstrData wrapper on the MapData
// ... only for the first field.
return makeConstrData(
return convertEnumVariantDataToConstrData(
schema,
tag,
schema.variantTypes[tag].fieldTypes.map((f, i) =>
schemaToUplcWithDataPath(f.type, variantFields[f.name], {
defs,
dataPath: `${dataPath}[${schema.name}::${variantName}].${f.name}`
})
)
variantFields,
passContext(context, dataPath)
)

@@ -440,6 +479,10 @@ }

schema.fieldTypes.map(({ name, type }) =>
schemaToUplcWithDataPath(type, x[name], {
defs,
dataPath: `${dataPath}[enumVariant ${schema.id}.${name}`
})
convertSchemaDataToUplcDataWithDataPath(
type,
x[name],
passContext(
context,
`${dataPath}[enumVariant ${schema.id}.${name}`
)
)
)

@@ -453,2 +496,43 @@ )

/**
* Gives the encoding of nested data a context to prevent a second ConstrData wrapper on the MapData
* ... only for the first field.
* @param {EnumTypeSchema} schema
* @param {number} tag
* @param {any} data - can be any in order to represent a single unwrapped field
* @param {SchemaToUplcContext} context
* @returns {ConstrData}
*/
function convertEnumVariantDataToConstrData(schema, tag, data, context) {
const variantSchema = schema.variantTypes[tag]
const variantName = variantSchema.name
if (
context.unwrapSingleFieldEnumVariants &&
variantSchema.fieldTypes.length == 1
) {
const singleFieldName = variantSchema.fieldTypes[0].name
// rewrap as preparation for converting to UplcData
data = {
[singleFieldName]: data
}
}
// at this point `data` should be of type `Record<string, any>`
return makeConstrData(
tag,
variantSchema.fieldTypes.map((f) =>
convertSchemaDataToUplcDataWithDataPath(
f.type,
data[f.name],
passContext(
context,
`[${schema.name}::${variantName}].${f.name}`
)
)
)
)
}
/**
* @param {TypeSchema} schema

@@ -459,3 +543,3 @@ * @param {UplcData} data

*/
function uplcToSchemaWithDataPath(schema, data, context) {
function convertUplcDataToSchemaDataWithDataPath(schema, data, context) {
try {

@@ -480,11 +564,8 @@ const t = uplcToSchema(schema, data, context)

* @param {UplcData} data
* @param {UplcToSchemaContext} inputContextOnly
* @param {UplcToSchemaContext} context
* @returns {any}
*/
function uplcToSchema(schema, data, inputContextOnly) {
function uplcToSchema(schema, data, context) {
const kind = schema.kind
const { config, defs } = inputContextOnly
// Note: don't use the inputContext directly in nested calls.
const { dataPath, ...context } = inputContextOnly
// use { ... context } augmented with a de-novo `dataPath` attr
const { dataPath, defs, isMainnet } = context

@@ -497,6 +578,3 @@ switch (kind) {

case "Address":
return convertUplcDataToShelleyAddress(
config.isMainnet,
data
)
return convertUplcDataToShelleyAddress(isMainnet, data)
case "Any":

@@ -555,5 +633,5 @@ // TODO: should this throw an error?

case "TxInput":
return convertUplcDataToTxInput(config.isMainnet, data)
return convertUplcDataToTxInput(isMainnet, data)
case "TxOutput":
return convertUplcDataToTxOutput(config.isMainnet, data)
return convertUplcDataToTxOutput(isMainnet, data)
case "TxOutputDatum":

@@ -573,6 +651,7 @@ return convertUplcDataToTxOutputDatum(data)

return expectListData(data).items.map((x, i) =>
uplcToSchemaWithDataPath(schema.itemType, x, {
...context,
dataPath: `${dataPath}[${i}]`
})
convertUplcDataToSchemaDataWithDataPath(
schema.itemType,
x,
passContext(context, `${dataPath}[${i}]`)
)
)

@@ -582,6 +661,7 @@ case "map":

expectMapData(data).items.map(([k, v], i) => {
const key = uplcToSchemaWithDataPath(schema.keyType, k, {
...context,
dataPath: `${dataPath}[mapKey @${i}]`
})
const key = convertUplcDataToSchemaDataWithDataPath(
schema.keyType,
k,
passContext(context, `${dataPath}[mapKey @${i}]`)
)
const displayKey =

@@ -591,6 +671,10 @@ "string" == typeof key ? `'${key}'` : `@{i}`

key,
uplcToSchemaWithDataPath(schema.valueType, v, {
...context,
dataPath: `${dataPath}[mapVal ${displayKey}]`
})
convertUplcDataToSchemaDataWithDataPath(
schema.valueType,
v,
passContext(
context,
`${dataPath}[mapVal ${displayKey}]`
)
)
]

@@ -601,6 +685,7 @@ })

return expectListData(data).items.map((x, i) =>
uplcToSchemaWithDataPath(schema.itemTypes[i], x, {
...context,
dataPath: `${dataPath}[tuple@${i}]`
})
convertUplcDataToSchemaDataWithDataPath(
schema.itemTypes[i],
x,
passContext(context, `${dataPath}[tuple@${i}]`)
)
)

@@ -610,6 +695,7 @@ case "option": {

return optionData
? uplcToSchemaWithDataPath(schema.someType, optionData, {
...context,
dataPath: `${dataPath}::Some`
})
? convertUplcDataToSchemaDataWithDataPath(
schema.someType,
optionData,
passContext(context, `${dataPath}::Some`)
)
: undefined

@@ -622,7 +708,8 @@ }

return {
[schema.fieldTypes[0].name]: uplcToSchemaWithDataPath(
schema.fieldTypes[0].type,
data,
{ ...context, dataPath: `${dataPath}[sfStruct]` }
)
[schema.fieldTypes[0].name]:
convertUplcDataToSchemaDataWithDataPath(
schema.fieldTypes[0].type,
data,
passContext(context, `${dataPath}[sfStruct]`)
)
}

@@ -644,6 +731,10 @@ case "list": {

name,
uplcToSchemaWithDataPath(type, field, {
...context,
dataPath: `${dataPath}[fStruct].${name}`
})
convertUplcDataToSchemaDataWithDataPath(
type,
field,
passContext(
context,
`${dataPath}[fStruct].${name}`
)
)
]

@@ -709,9 +800,9 @@ })

name,
uplcToSchemaWithDataPath(
convertUplcDataToSchemaDataWithDataPath(
type,
encodedDataPair[1],
{
...context,
dataPath: `${dataPath}[mStruct].${name}`
}
passContext(
context,
`${dataPath}[mStruct].${name}`
)
)

@@ -732,34 +823,8 @@ ])

defs[schema.id] = schema
const { tag, fields } = expectConstrData(data)
const variantSchema = schema.variantTypes[tag]
if (!variantSchema) {
throw new Error(`tag ${tag} out of range`)
}
const nExpected = variantSchema.fieldTypes.length
if (fields.length != nExpected) {
throw new Error(
`expected ${nExpected} fields for variant ${variantSchema.name} (tag ${tag}), got ${fields.length} fields`
)
}
const fieldCount = variantSchema.fieldTypes.length
return {
[variantSchema.name]: Object.fromEntries(
fields.map((f, i) => [
variantSchema.fieldTypes[i].name,
uplcToSchemaWithDataPath(
variantSchema.fieldTypes[i].type,
f,
{
...context,
dataPath: `${dataPath}[${schema.name}::${variantSchema.name}]`
}
)
])
)
}
return convertConstrDataFieldsToEnumVariantFields(
schema,
expectConstrData(data),
passContext(context, dataPath)
)
}

@@ -773,6 +838,10 @@ case "variant": {

schema.fieldTypes[i].name,
uplcToSchemaWithDataPath(schema.fieldTypes[i].type, field, {
...context,
dataPath: `${dataPath}[enumVariant ${schema.id}].${schema.fieldTypes[i].name}`
})
convertUplcDataToSchemaDataWithDataPath(
schema.fieldTypes[i].type,
field,
passContext(
context,
`${dataPath}[enumVariant ${schema.id}].${schema.fieldTypes[i].name}`
)
)
])

@@ -787,2 +856,52 @@ )

/**
* @param {EnumTypeSchema} schema
* @param {ConstrData} data
* @param {UplcToSchemaContext} context
* @returns {Record<string, any>}
*/
function convertConstrDataFieldsToEnumVariantFields(schema, data, context) {
const { tag, fields } = data
const variantSchema = schema.variantTypes[tag]
if (!variantSchema) {
throw new Error(`tag ${tag} out of range`)
}
const nExpected = variantSchema.fieldTypes.length
if (fields.length != nExpected) {
throw new Error(
`expected ${nExpected} fields for variant ${variantSchema.name} (tag ${tag}), got ${fields.length} fields`
)
}
const result = {
[variantSchema.name]: Object.fromEntries(
fields.map((f, i) => [
variantSchema.fieldTypes[i].name,
convertUplcDataToSchemaDataWithDataPath(
variantSchema.fieldTypes[i].type,
f,
passContext(
context,
`${context.dataPath}[${schema.name}::${variantSchema.name}]`
)
)
])
)
}
if (
context.unwrapSingleFieldEnumVariants &&
variantSchema.fieldTypes.length == 1
) {
const singleFieldName = variantSchema.fieldTypes[0].name
const variantName = variantSchema.name
result[variantName] = result[variantName][singleFieldName]
}
return result
}
/**
* @template TStrict

@@ -789,0 +908,0 @@ * @template TPermissive

@@ -125,4 +125,6 @@ export { makeCast, makeUserFunc } from "./cast/index.js"

/**
* `unwrapSingleFieldEnumVariants` defaults to false. If true, the following enum variant data structure is used: `{VariantName: SingleFieldData}`, instead of the more verbose `{VariantName: {SingleFieldName: SingleFieldData}}`
* @typedef {{
* isMainnet: boolean
* unwrapSingleFieldEnumVariants?: boolean
* }} CastConfig

@@ -161,15 +163,2 @@ */

/**
* @typedef {Object} SchemaToUplcContext
* @prop {Record<string, TypeSchema>} defs - symbol table permitting recursive schema references
* @prop {string} dataPath - provides developer-facing cues for any parsing errors, showing the deep field path of any error
*/
/**
* @typedef {Object} UplcToSchemaContext
* @prop {Record<string, TypeSchema>} defs - symbol table permitting recursive schema references
* @prop {string} dataPath - provides developer-facing cues for any parsing errors, showing the deep field path of any error
* @prop {CastConfig} config - has isMainnet indicator
*/
/**
* TODO: add logOptions here as well (which can be overridden by logOptions passed directly to eval(), evalUnsafe() and profile())?

@@ -176,0 +165,0 @@ * `returns` is optional to accomodate main functions that return void

/**
* @import { TxInput, TxOutput } from "@helios-lang/ledger"
* @import { TypeSchema } from "@helios-lang/type-utils"
* @import { UplcData } from "@helios-lang/uplc"
* @import { Cast, CastConfig, CastLike, SchemaToUplcContext, UplcToSchemaContext } from "../index.js"
* @import { EnumTypeSchema, TypeSchema } from "@helios-lang/type-utils"
* @import { ConstrData, UplcData } from "@helios-lang/uplc"
* @import { Cast, CastConfig, CastLike } from "../index.js"
*/
/**
* @typedef {Object} SchemaToUplcContext
* @prop {Record<string, TypeSchema>} defs - symbol table permitting recursive schema references
* @prop {string} dataPath - provides developer-facing cues for any parsing errors, showing the deep field path of any error
* @prop {boolean} unwrapSingleFieldEnumVariants - defaults to false. If true, assumes the following input objects for enum variants: `{VariantName: SingleFieldData}`, instead of the more verbose `{VariantName: {SingleFieldName: SingleFieldData}}`
*/
/**
* @typedef {Object} UplcToSchemaContext
* @prop {Record<string, TypeSchema>} defs - symbol table permitting recursive schema references
* @prop {string} dataPath - provides developer-facing cues for any parsing errors, showing the deep field path of any error
* @prop {boolean} unwrapSingleFieldEnumVariants - defaults to false. If true, the following enum variant outputs are created: `{VariantName: SingleFieldData}`, instead of the more verbose `{VariantName: {SingleFieldName: SingleFieldData}}`
* @prop {boolean} isMainnet
*/
/**
* @template TStrict

@@ -23,2 +36,31 @@ * @template TPermissive=TStrict

export function configureCast<TStrict, TPermissive>(cast: CastLike<TStrict, TPermissive>, config: CastConfig): Cast<TStrict, TPermissive>;
export type SchemaToUplcContext = {
/**
* - symbol table permitting recursive schema references
*/
defs: Record<string, TypeSchema>;
/**
* - provides developer-facing cues for any parsing errors, showing the deep field path of any error
*/
dataPath: string;
/**
* - defaults to false. If true, assumes the following input objects for enum variants: `{VariantName: SingleFieldData}`, instead of the more verbose `{VariantName: {SingleFieldName: SingleFieldData}}`
*/
unwrapSingleFieldEnumVariants: boolean;
};
export type UplcToSchemaContext = {
/**
* - symbol table permitting recursive schema references
*/
defs: Record<string, TypeSchema>;
/**
* - provides developer-facing cues for any parsing errors, showing the deep field path of any error
*/
dataPath: string;
/**
* - defaults to false. If true, the following enum variant outputs are created: `{VariantName: SingleFieldData}`, instead of the more verbose `{VariantName: {SingleFieldName: SingleFieldData}}`
*/
unwrapSingleFieldEnumVariants: boolean;
isMainnet: boolean;
};
import type { TypeSchema } from "@helios-lang/type-utils";

@@ -28,2 +70,3 @@ import type { CastConfig } from "../index.js";

import type { CastLike } from "../index.js";
import type { TypeSchema as TypeSchema_1 } from "@helios-lang/type-utils";
//# sourceMappingURL=Cast.d.ts.map

@@ -92,4 +92,8 @@ export { makeLoadedScriptsWriter } from "./codegen/index.js";

export type DagDependencies = Record<string, string[]>;
/**
* `unwrapSingleFieldEnumVariants` defaults to false. If true, the following enum variant data structure is used: `{VariantName: SingleFieldData}`, instead of the more verbose `{VariantName: {SingleFieldName: SingleFieldData}}`
*/
export type CastConfig = {
isMainnet: boolean;
unwrapSingleFieldEnumVariants?: boolean;
};

@@ -114,26 +118,2 @@ export type Cast<TStrict, TPermissive> = {

export type CastLike<TStrict, TPermissive> = Cast<TStrict, TPermissive> | ConfigurableCast<TStrict, TPermissive>;
export type SchemaToUplcContext = {
/**
* - symbol table permitting recursive schema references
*/
defs: Record<string, TypeSchema>;
/**
* - provides developer-facing cues for any parsing errors, showing the deep field path of any error
*/
dataPath: string;
};
export type UplcToSchemaContext = {
/**
* - symbol table permitting recursive schema references
*/
defs: Record<string, TypeSchema>;
/**
* - provides developer-facing cues for any parsing errors, showing the deep field path of any error
*/
dataPath: string;
/**
* - has isMainnet indicator
*/
config: CastConfig;
};
/**

@@ -140,0 +120,0 @@ * TODO: add logOptions here as well (which can be overridden by logOptions passed directly to eval(), evalUnsafe() and profile())?

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc