diff --git a/conway-cddl/codegen/generators/array.ts b/conway-cddl/codegen/generators/array.ts index 0dfba10..95fd8bb 100644 --- a/conway-cddl/codegen/generators/array.ts +++ b/conway-cddl/codegen/generators/array.ts @@ -2,11 +2,11 @@ import { CodeGeneratorBase, CodeGeneratorBaseOptions } from "."; import { SchemaTable } from ".."; export type GenArrayOptions = { - item: string; + item: string | undefined; } & CodeGeneratorBaseOptions; export class GenArray extends CodeGeneratorBase { - item: string; + item: string | undefined; constructor( name: string, @@ -18,60 +18,89 @@ export class GenArray extends CodeGeneratorBase { } private itemJsType() { - return this.typeUtils.jsType(this.item); + return this.item ? `${this.typeUtils.jsType(this.item)}` : undefined; } generateMembers(): string { - return `private items: ${this.itemJsType()}[];`; + const jsType = this.itemJsType(); + return ` + private items: ${jsType ? `${jsType}[]` : `Uint32Array`}; + private definiteEncoding: boolean; + `; } generateConstructor(): string { + const jsType = this.itemJsType(); return ` - constructor(items: ${this.itemJsType()}[]) { + constructor(items: ${jsType ? `${jsType}[]` : `Uint32Array`}, definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } `; } generateExtraMethods(): string { - let itemJsType = this.typeUtils.jsType(this.item); + let jsType = this.itemJsType(); return ` static new(): ${this.name} { - return new ${this.name}([]); + return new ${this.name}(${jsType ? "[]" : "new Uint32Array([])"}); } len(): number { return this.items.length; } - get(index: number): ${itemJsType} { - if(index >= this.items.length) throw new Error("Array out of bounds"); - return this.items[index]; - } + ${jsType ? + ` + get(index: number): ${jsType} { + if(index >= this.items.length) throw new Error("Array out of bounds"); + return this.items[index]; + } - add(elem: ${itemJsType}): void { - this.items.push(elem); + add(elem: ${jsType}): void { + this.items.push(elem); + } + ` : '' } `; } generateDeserialize(reader: string, path: string): string { - return ` - return new ${this.name}( - ${reader}.readArray( - (reader, idx) => ${this.typeUtils.readType("reader", this.item, `[...${path}, "Elem#" + idx]`)} - , ${path} - ) - ); - `; + if (this.item) { + return ` + const { items, definiteEncoding } = + ${reader}.readArray( + (reader, idx) => ${this.typeUtils.readType("reader", this.item, `[...${path}, "Elem#" + idx]`)} + , ${path} + ) + return new ${this.name}(items, definiteEncoding); + `; + } else { + return ` + const { items, definiteEncoding } = + ${reader}.readArray( + (reader, idx) => Number(reader.readUint([...${path}, "Byte#" + idx])) + , ${path} + ) + + return new ${this.name}(new Uint32Array(items), definiteEncoding); + `; + } } generateSerialize(writer: string): string { - return ` - ${writer}.writeArray( - this.items, - (writer, x) => ${this.typeUtils.writeType("writer", "x", this.item)} - ); - `; + if (this.item) { + return ` + ${writer}.writeArray( + this.items, + (writer, x) => ${this.typeUtils.writeType("writer", "x", this.item)}, + this.definiteEncoding + ); + `; + } else { + return ` + ${writer}.writeArray(this.items, (writer, x) => writer.writeInt(BigInt(x)), this.definiteEncoding) + ` + } } } diff --git a/conway-cddl/codegen/generators/index.ts b/conway-cddl/codegen/generators/index.ts index 1548f46..5701f45 100644 --- a/conway-cddl/codegen/generators/index.ts +++ b/conway-cddl/codegen/generators/index.ts @@ -267,8 +267,6 @@ export class TypeUtils { return yamlType; case "bytes": return "Uint8Array"; - case "arrayToUint32Array": - return "Uint32Array"; default: console.error("Unknown type: " + yamlType); return "unknown"; @@ -292,8 +290,6 @@ export class TypeUtils { return `${reader}.readBoolean(${path})`; case "bytes": return `${reader}.readBytes(${path})`; - case "arrayToUint32Array": - return `new Uint32Array(${reader}.readArray((reader) => Number(reader.readUint(${path})), ${path}));`; default: console.error("Can't decode: " + type); return `$$CANT_READ("${type}")`; @@ -317,8 +313,6 @@ export class TypeUtils { return `${writer}.writeBoolean(${value})`; case "bytes": return `${writer}.writeBytes(${value})`; - case "arrayToUint32Array": - return `${writer}.writeArray(${value}, (writer, x) => writer.writeInt(BigInt(x)))`; default: console.error("Can't encode: " + type); return `$$CANT_WRITE("${type}")`; @@ -338,8 +332,6 @@ export class TypeUtils { case "boolean": return `${var1} === ${var2}`; case "bytes": - case "arrayToUint32Array": - return `arrayEq(${var1}, ${var2})`; default: console.error("Can't compare: " + type); return `$$CANT_EQ("${type}")`; diff --git a/conway-cddl/codegen/generators/set.ts b/conway-cddl/codegen/generators/set.ts index d8fb70b..37e9de5 100644 --- a/conway-cddl/codegen/generators/set.ts +++ b/conway-cddl/codegen/generators/set.ts @@ -20,13 +20,21 @@ export class GenSet extends CodeGeneratorBase { generateMembers(): string { return ` private items: ${this.itemJsType()}[]; + private definiteEncoding: boolean; + private nonEmptyTag: boolean; + + private setItems(items: ${this.itemJsType()}[]) { + this.items = items; + } `; } generateConstructor(): string { return ` - constructor() { + constructor(definiteEncoding: boolean = true, nonEmptyTag: boolean = true) { this.items = []; + this.definiteEncoding = definiteEncoding; + this.nonEmptyTag = nonEmptyTag; } `; } @@ -66,19 +74,31 @@ export class GenSet extends CodeGeneratorBase { generateDeserialize(reader: string, path: string): string { return ` - let ret = new ${this.name}(); + let nonEmptyTag = false; if(${reader}.peekType(${path}) == "tagged") { let tag = ${reader}.readTaggedTag(${path}); - if(tag != 258) throw new Error("Expected tag 258. Got " + tag); + if(tag != 258) { + throw new Error("Expected tag 258. Got " + tag); + } else { + nonEmptyTag = true; + } } - ${reader}.readArray((reader, idx) => ret.add(${this.typeUtils.readType(reader, this.item, `[...${path}, '${this.item}#' + idx]`)}), ${path}); + const { items, definiteEncoding } = ${reader}.readArray( + (reader, idx) => + ${this.typeUtils.readType( reader, this.item, `[...${path}, '${this.item}#' + idx]`)}, + ${path} + ); + let ret = new ${this.name}(definiteEncoding, nonEmptyTag); + ret.setItems(items); return ret; `; } generateSerialize(writer: string): string { return ` - ${writer}.writeTaggedTag(258); + if (this.nonEmptyTag) { + ${writer}.writeTaggedTag(258); + } ${writer}.writeArray(this.items, (writer, x) => ${this.typeUtils.writeType("writer", "x", this.item)}); `; } diff --git a/conway-cddl/codegen/generators/structured/index.ts b/conway-cddl/codegen/generators/structured/index.ts index 9b077a1..35c8085 100644 --- a/conway-cddl/codegen/generators/structured/index.ts +++ b/conway-cddl/codegen/generators/structured/index.ts @@ -38,6 +38,10 @@ export class GenStructuredBase< return this.options.fields; } + getMinFields(): number { + return this.options.fields.filter((v) => !v.optional).length + } + generateMembers(): string { return this.options.fields .map((x) => `private _${x.name}: ${this.fieldType(x)};`) diff --git a/conway-cddl/codegen/generators/structured/record.ts b/conway-cddl/codegen/generators/structured/record.ts index d93e5c5..4d13958 100644 --- a/conway-cddl/codegen/generators/structured/record.ts +++ b/conway-cddl/codegen/generators/structured/record.ts @@ -5,6 +5,7 @@ export type Field = { name: string; type: string; nullable?: boolean; + optional?: boolean; }; export type GenRecordOptions = { @@ -24,21 +25,23 @@ export class GenRecord extends GenStructuredBase { return ` let len = ${reader}.readArrayTag(${path}); - if(len != null && len < ${this.getFields().length}) { - throw new Error("Insufficient number of fields in record. Expected ${this.getFields().length}. Received " + len + "(at " + path.join("/")); + if(len != null && len < ${this.getMinFields()}) { + throw new Error("Insufficient number of fields in record. Expected at least ${this.getMinFields()}. Received " + len + "(at " + path.join("/")); } - ${this.getFields() - .map( - (x) => ` - const ${x.name}_path = [...${path}, '${x.type}(${x.name})']; - let ${x.name} = ${ - x.nullable - ? `${reader}.readNullable(r => ${this.typeUtils.readType("r", x.type, `${x.name}_path`)}, ${path})?? undefined` - : this.typeUtils.readType(reader, x.type, `${x.name}_path`) - };`, - ) - .join("\n")} + ${this.getFields().reduce((acc, x, idx) => { + acc.push(` + const ${x.name}_path = [...${path}, '${x.type}(${x.name})']; + let ${x.name} = ${ + x.optional ? + `len != null && len > ${idx} ? ${this.typeUtils.readType(reader, x.type, `${x.name}_path`)} : undefined` : + x.nullable ? + `${reader}.readNullable(r => ${this.typeUtils.readType("r", x.type, `${x.name}_path`)}, ${path})?? undefined` : + this.typeUtils.readType(reader, x.type, `${x.name}_path`) + } + `); + return acc; + }, [] as string[]).join("\n")} return new ${this.name}(${this.getFields() .map((x) => x.name) @@ -48,17 +51,30 @@ export class GenRecord extends GenStructuredBase { generateSerialize(writer: string): string { return ` - ${writer}.writeArrayTag(${this.getFields().length}); + let arrayLen = ${this.getMinFields()}; + ${this.getFields(). + map((x) => x.optional + ? `if(this._${x.name}) { + arrayLen++; + }` : + "") + .join("\n")} + + ${writer}.writeArrayTag(arrayLen); ${this.getFields() .map((x) => + x.optional + ? `if(this._${x.name}) { + ${this.typeUtils.writeType(writer, `this._${x.name}`, x.type)}; + }` : x.nullable ? `if(this._${x.name} == null) { ${writer}.writeNull(); } else { ${this.typeUtils.writeType(writer, `this._${x.name}`, x.type)}; - }` - : `${this.typeUtils.writeType(writer, `this._${x.name}`, x.type)};`, + }` : + `${this.typeUtils.writeType(writer, `this._${x.name}`, x.type)};`, ) .join("\n")} `; diff --git a/conway-cddl/codegen/generators/tagged_record.ts b/conway-cddl/codegen/generators/tagged_record.ts index d104ebe..8cc72f5 100644 --- a/conway-cddl/codegen/generators/tagged_record.ts +++ b/conway-cddl/codegen/generators/tagged_record.ts @@ -163,14 +163,18 @@ export class GenTaggedRecord extends CodeGeneratorBase { break; `, ) + .concat([` + default: + throw new Error("Unexpected tag for ${this.name}: " + tag + "(at " + ${path}.join("/") + ")"); + `]) .join("\n")} } if(len == null) { ${reader}.readBreak(); } - - throw new Error("Unexpected tag for ${this.name}: " + tag + "(at " + ${path}.join("/") + ")"); + + return new ${this.name}(variant); `; } diff --git a/conway-cddl/codegen/types.ts b/conway-cddl/codegen/types.ts index 91be13d..1318abd 100644 --- a/conway-cddl/codegen/types.ts +++ b/conway-cddl/codegen/types.ts @@ -16,7 +16,7 @@ export const Schema = Type.Intersect([ extra_methods: Type.Optional(Type.String()), }), Type.Union([ - Type.Object({ type: Type.Literal("array"), item: Type.String() }), + Type.Object({ type: Type.Literal("array"), item: Type.Optional(Type.String()) }), Type.Object({ type: Type.Literal("enum"), values: Type.Array( @@ -78,6 +78,7 @@ export const Schema = Type.Intersect([ name: Type.String(), type: Type.String(), nullable: Type.Optional(Type.Boolean()), + optional: Type.Optional(Type.Boolean()) }), ), accessor_get_prefix: Type.Optional(Type.Boolean()), diff --git a/conway-cddl/yaml/conway.yaml b/conway-cddl/yaml/conway.yaml index 83c2465..d5fc544 100644 --- a/conway-cddl/yaml/conway.yaml +++ b/conway-cddl/yaml/conway.yaml @@ -11,6 +11,32 @@ # ; length of transaction_bodies Block: type: record + methods: + new: null + extra_methods: | + static new( + header: Header, + transaction_bodies: TransactionBodies, + transaction_witness_sets: TransactionWitnessSets, + auxiliary_data_set: AuxiliaryDataSet, + invalid_transactions: Uint32Array + ): Block { + return new Block( + header, + transaction_bodies, + transaction_witness_sets, + auxiliary_data_set, + new InvalidTransactions(invalid_transactions) + ); + } + + invalid_transactions(): Uint32Array { + return this.inner_invalid_transactions().as_uint32Array(); + } + + set_invalid_transactions(invalid_transactions: Uint32Array) { + this._inner_invalid_transactions = new InvalidTransactions(invalid_transactions); + } fields: - name: header type: Header @@ -20,8 +46,8 @@ Block: type: TransactionWitnessSets - name: auxiliary_data_set type: AuxiliaryDataSet - - name: invalid_transactions - type: arrayToUint32Array + - name: inner_invalid_transactions + type: InvalidTransactions TransactionBodies: type: array @@ -46,6 +72,14 @@ AuxiliaryDataSet: return indices; } +# no item type means that it is encoded as a Uint32Array +InvalidTransactions: + type: array + extra_methods: | + as_uint32Array(): Uint32Array { + return this.items; + } + # transaction = # [ transaction_body # , transaction_witness_set @@ -674,20 +708,32 @@ TransactionInput: # ; Both of the Alonzo and Babbage style TxOut formats are equally valid # ; and can be used interchangeably # transaction_output = pre_babbage_transaction_output / post_alonzo_transaction_output -# -# pre_babbage_transaction_output = -# [ address -# , amount : value -# , ? datum_hash : $hash32 -# ] -# +TransactionOutput: + type: union + variants: + - tag: 0 + peek_type: array + name: pre_babbage_transaction_output + type: PreBabbageTransactionOutput + - tag: 1 + peek_type: map + name: post_alonzo_transaction_output + type: PostAlonzoTransactionOutput + methods: + new: null + extra_methods: | + static new(address: Address, amount: Value): TransactionOutput { + const post_alonzo_transaction_output = new PostAlonzoTransactionOutput(address, amount, undefined, undefined); + return new TransactionOutput({kind: 1, value: post_alonzo_transaction_output}); + } + # post_alonzo_transaction_output = # { 0 : address # , 1 : value # , ? 2 : datum_option ; datum option # , ? 3 : script_ref ; script reference # } -TransactionOutput: +PostAlonzoTransactionOutput: type: struct fields: - id: 0 @@ -697,19 +743,31 @@ TransactionOutput: name: amount type: Value - id: 2 - name: plutus_data - type: PlutusData + name: datum_option + type: DataOption optional: true - id: 3 name: script_ref type: ScriptRef optional: true - methods: - new: null - extra_methods: | - static new(address: Address, amount: Value): TransactionOutput { - return new TransactionOutput(address, amount, undefined, undefined); - } + +# pre_babbage_transaction_output = +# [ address +# , amount : value +# , ? datum_hash : $hash32 +# ] +# +PreBabbageTransactionOutput: + type: record + fields: + - name: address + type: Address + - name: amount + type: Value + - name: datum_hash + type: DataHash + optional: true + # script_data_hash = $hash32 # ; This is a hash of data which may affect evaluation of a script. @@ -1549,8 +1607,8 @@ TransactionWitnessSet: type: PlutusScripts optional: true - id: 4 - name: plutus_data - type: PlutusList + name: inner_plutus_data + type: PlutusSet optional: true - id: 5 name: redeemers @@ -1580,20 +1638,28 @@ TransactionWitnessSet: ); } + plutus_data(): PlutusList | undefined { + return this.inner_plutus_data()?.as_list(); + } + + set_plutus_data(plutus_data: PlutusList): void { + this._inner_plutus_data = plutus_data.as_set(); + } + Vkeywitnesses: type: set item: Vkeywitness NativeScripts: - type: array + type: set item: NativeScript BootstrapWitnesses: - type: array + type: set item: BootstrapWitness PlutusScripts: - type: array + type: set item: PlutusScript PlutusScript: @@ -1609,9 +1675,13 @@ PlutusScript: return new ScriptHash(hash_bytes); } -PlutusList: +PlutusSet: type: set item: PlutusData + extra_methods: | + as_list(): PlutusList { + return new PlutusList(this.items, this.definiteEncoding); + } # ; The real type of plutus_v1_script, plutus_v2_script and plutus_v3_script is bytes. # ; However, because we enforce uniqueness when many scripts are supplied, @@ -1764,34 +1834,32 @@ TransactionMetadatumLabels: # , ? 4 => [ * plutus_v3_script ] # }) AuxiliaryData: - type: struct - fields: - - id: 0 - name: metadata + type: union + variants: + - tag: 0 + peek_type: map + name: shelley_metadata type: GeneralTransactionMetadata - - id: 1 - name: native_scripts - type: NativeScripts - - id: 2 - name: plutus_scripts_v1 - type: PlutusScripts - - id: 3 - name: plutus_scripts_v2 - type: PlutusScripts - - id: 4 - name: plutus_scripts_v3 - type: PlutusScripts + - tag: 1 + peek_type: array + name: shelley_metadata_ma + type: AuxiliaryDataShelleyMa + - tag: 2 + peek_type: tagged + name: postalonzo_metadata + type: AuxiliaryDataPostAlonzo methods: new: null extra_methods: | static new(): AuxiliaryData { - return new AuxiliaryData( + const post_alonzo_auxiliary_data = new AuxiliaryDataPostAlonzo( GeneralTransactionMetadata.new(), NativeScripts.new(), PlutusScripts.new(), PlutusScripts.new(), PlutusScripts.new(), - ) + ); + return new AuxiliaryData({kind: 2, value: post_alonzo_auxiliary_data}) } # vkeywitness = [ $vkey, $signature ] @@ -1988,6 +2056,12 @@ NetworkId: # datum_hash = $hash32 # data = #6.24(bytes .cbor plutus_data) +Data: + type: newtype + item: bytes + accessor: encoded_plutus_data + tagged: + tag: 24 # datum_option = [ 0, $hash32 // 1, data ] DataOption: @@ -1998,7 +2072,7 @@ DataOption: value: DataHash - name: data tag: 1 - value: PlutusData + value: Data # script_ref = #6.24(bytes .cbor script) @@ -2046,6 +2120,18 @@ ProposedProtocolParameterUpdates: value: ProtocolParamUpdate keys_method_type: GenesisHashes +PlutusList: + type: array + item: PlutusData + extra_methods: | + as_set(): PlutusSet { + let set = new PlutusSet(this.definiteEncoding); + for (let i = 0; i < this.len(); i++) { + set.add(this.items[i]); + } + return set; + } + PlutusMap: type: map key: PlutusData @@ -2095,6 +2181,20 @@ Vkey: fields: - name: public_key type: PublicKey + methods: + deserialize: null + serialize: null + extra_methods: | + static deserialize(reader: CBORReader, path: string[]): Vkey { + const public_key_path = [...path, "PublicKey(public_key)"]; + let public_key = PublicKey.deserialize(reader, public_key_path); + return new Vkey(public_key); + } + + serialize(writer: CBORWriter): void { + this._public_key.serialize(writer); + } + Vkeys: type: array item: Vkey diff --git a/conway-cddl/yaml/custom/auxiliary_data.yaml b/conway-cddl/yaml/custom/auxiliary_data.yaml new file mode 100644 index 0000000..b07d32c --- /dev/null +++ b/conway-cddl/yaml/custom/auxiliary_data.yaml @@ -0,0 +1,42 @@ +# [ transaction_metadata: metadata ; Shelley-ma +# , auxiliary_scripts: [ * native_script ] +# ] +AuxiliaryDataShelleyMa: + type: record_fragment + fields: + - name: transaction_metadata + type: GeneralTransactionMetadata + - name: auxiliary_scripts + type: NativeScripts + +# #6.259({ ? 0 => metadata ; Alonzo and beyond +# , ? 1 => [ * native_script ] +# , ? 2 => [ * plutus_v1_script ] +# , ? 3 => [ * plutus_v2_script ] +# , ? 4 => [ * plutus_v3_script ] +# }) +AuxiliaryDataPostAlonzo: + type: struct + fields: + - id: 0 + name: metadata + type: GeneralTransactionMetadata + optional: true + - id: 1 + name: native_scripts + type: NativeScripts + optional: true + - id: 2 + name: plutus_scripts_v1 + type: PlutusScripts + optional: true + - id: 3 + name: plutus_scripts_v2 + type: PlutusScripts + optional: true + - id: 4 + name: plutus_scripts_v3 + type: PlutusScripts + optional: true + tagged: + tag: 259 diff --git a/conway-cddl/yaml/custom/constr_plutus_data.yaml b/conway-cddl/yaml/custom/constr_plutus_data.yaml index facb6d7..c7a7eb9 100644 --- a/conway-cddl/yaml/custom/constr_plutus_data.yaml +++ b/conway-cddl/yaml/custom/constr_plutus_data.yaml @@ -5,3 +5,46 @@ ConstrPlutusData: type: BigNum - name: data type: PlutusList + methods: + deserialize: deserializeWithSeparateIdx + serialize: serializeWithSeparateIdx + new: uncheckedNew + extra_methods: | + static deserialize(reader: CBORReader, path: string[]): ConstrPlutusData { + const alternative = reader.readTaggedTagAsBigInt(path); + if (Number(alternative) >= 121 && Number(alternative) <= 127) { + return ConstrPlutusData.new(BigNum.new(alternative), PlutusList.deserialize(reader, [...path, 'PlutusList(data)'])) + } else if (Number(alternative) == 102) { + return ConstrPlutusData.deserializeWithSeparateIdx(reader, path); + } else { + throw new Error( + "Unexpected alternative for ConstrPlutusData: " + + alternative + + "(at " + + path.join("/") + + ")", + ); + } + } + + serialize(writer: CBORWriter): void { + const alternative = this.alternative().toJsValue(); + writer.writeTaggedTag(Number(alternative)); + if (alternative == 102n) { + this.serializeWithSeparateIdx(writer) + } else { + this.data().serialize(writer); + } + } + + static new(alternative: BigNum, data: PlutusList): ConstrPlutusData { + const alt = Number(alternative.toJsValue()); + if(alt != 102 && (alt < 121 || alt > 127)) { + throw new Error( + "Unexpected alternative for ConstrPlutusData: " + alternative + ); + } else { + return ConstrPlutusData.uncheckedNew(alternative, data); + } + } + diff --git a/conway-cddl/yaml/custom/redeemers.yaml b/conway-cddl/yaml/custom/redeemers.yaml index 1db1b41..7513561 100644 --- a/conway-cddl/yaml/custom/redeemers.yaml +++ b/conway-cddl/yaml/custom/redeemers.yaml @@ -1,81 +1,97 @@ -Redeemer: - type: record - fields: - - name: tag - type: RedeemerTag - - name: index - type: BigNum - - name: data - type: PlutusData - - name: ex_units - type: ExUnits - Redeemers: - type: array - item: Redeemer - methods: - serialize: null - deserialize: null + type: union + variants: + - tag: 0 + peek_type: "array" + name: redeemers_array + type: RedeemersArray + - tag: 1 + peek_type: "map" + name: redeemers_map + type: RedeemersMap extra_methods: | total_ex_units(): ExUnits { - let mems = BigNum.zero(), steps = BigNum.zero(); - for(let item of this.items) { - mems = mems.checked_add(item.ex_units().mem()); - steps = steps.checked_add(item.ex_units().steps()); + let mems = BigNum.zero(), + steps = BigNum.zero(); + switch(this.variant.kind) { + case 0: { + for (let i = 0; i < this.variant.value.len(); i++) { + const item = this.variant.value.get(i); + mems = mems.checked_add(item.ex_units().mem()); + steps = steps.checked_add(item.ex_units().steps()); + } + break; + } + case 1: { + const keys = this.variant.value.keys(); + for (let i = 0; i < keys.len(); i++) { + const item = this.variant.value.get(keys.get(i)) as RedeemersValue; + mems = mems.checked_add(item.ex_units().mem()); + steps = steps.checked_add(item.ex_units().steps()); + } + break; + } } return ExUnits.new(mems, steps); } - static deserialize(reader: CBORReader, path: string[]): Redeemers { - if(reader.peekType(path) == 'array') { - return Redeemers.deserializeArray(reader, path); - } else if(reader.peekType(path) == 'map') { - return Redeemers.deserializeMap(reader, path); - } - throw new Error("Expected either an array or a map (at " + path.join("/") + ")"); + static new(): Redeemers { + return Redeemers.new_redeemers_map(RedeemersMap.new()); } - static deserializeArray(reader: CBORReader, path: string[]): Redeemers { - let redeemers = Redeemers.new(); - reader.readArray((reader, idx) => { - let item = RedeemersArrayItem.deserialize(reader, [...path, 'RedeemersArrayItem#' + idx]); - redeemers.add( - Redeemer.new( - item.tag(), - item.index(), - item.data(), - item.ex_units(), - ) - ) - }, path); - return redeemers; + len(): number { + return this.variant.value.len() } - static deserializeMap(reader: CBORReader, path: string[]): Redeemers { - let redeemers = Redeemers.new(); - reader.readMap((reader, idx) => { - let key = RedeemersKey.deserialize(reader, [...path, `RedeemersKey#${idx}`]); - let value = RedeemersValue.deserialize(reader, [...path, `RedeemersValue#${idx}`]); - redeemers.add( - Redeemer.new( - key.tag(), - key.index(), - value.data(), - value.ex_units(), - ) - ) - }, path); - return redeemers; + add(elem: Redeemer): void { + switch(this.variant.kind) { + case 0: + this.variant.value.add(elem.redeemerArrayItem()); + break; + case 1: { + const r = elem.redeemerArrayItem(); + this.variant.value.insert( + RedeemersKey.new(r.tag(), r.index()), + RedeemersValue.new(r.data(), r.ex_units()) + ); + break; + } + } } - serialize(writer: CBORWriter): void { - writer.writeMap(this.items, (writer, redeemer) => { - let key = RedeemersKey.new(redeemer.tag(), redeemer.index()); - let value = RedeemersValue.new(redeemer.data(), redeemer.ex_units()); - key.serialize(writer); - value.serialize(writer); - }); + get(index: number): Redeemer { + switch(this.variant.kind) { + case 0: + return new Redeemer(this.variant.value.get(index)); + case 1: { + const key = this.variant.value.keys().get(index); + const r = this.variant.value.get(key); + if (r === undefined) { + throw('Unexpected undefined key in Redeemers'); + } else { + return new Redeemer(RedeemersArrayItem.new(key.tag(), key.index(), r.data(), r.ex_units())); + } + } + } + } + + +# This class is only added for compliance with the CSL interface. It's not +# used directly in a serialized transaction. +Redeemer: + type: newtype + item: RedeemersArrayItem + methods: + new: null + extra_methods: | + static new(tag: RedeemerTag, index: BigNum, data: PlutusData, ex_units: ExUnits) { + return new Redeemer(new RedeemersArrayItem(tag, index, data, ex_units)); } + accessor: redeemerArrayItem + +RedeemersArray: + type: array + item: RedeemersArrayItem RedeemersArrayItem: type: record @@ -90,6 +106,16 @@ RedeemersArrayItem: - name: ex_units type: ExUnits +RedeemersMap: + type: map + key: RedeemersKey + value: RedeemersValue + keys_method_type: RedeemersKeys + +RedeemersKeys: + type: array + item: RedeemersKey + RedeemersKey: type: record export: false diff --git a/csl-types/cardano-data-lite.d.ts b/csl-types/cardano-data-lite.d.ts index 219e1b4..5c82858 100644 --- a/csl-types/cardano-data-lite.d.ts +++ b/csl-types/cardano-data-lite.d.ts @@ -47,7 +47,8 @@ export declare class AssetName { } export declare class AssetNames { private items; - constructor(items: AssetName[]); + private definiteEncoding; + constructor(items: AssetName[], definiteEncoding?: boolean); static new(): AssetNames; len(): number; get(index: number): AssetName; @@ -83,23 +84,31 @@ export declare class Assets { _normalize(): void; _partial_cmp(rhs: Assets): number | undefined; } +export declare enum AuxiliaryDataKind { + GeneralTransactionMetadata = 0, + AuxiliaryDataShelleyMa = 1, + AuxiliaryDataPostAlonzo = 2 +} +export type AuxiliaryDataVariant = { + kind: 0; + value: GeneralTransactionMetadata; +} | { + kind: 1; + value: AuxiliaryDataShelleyMa; +} | { + kind: 2; + value: AuxiliaryDataPostAlonzo; +}; export declare class AuxiliaryData { - private _metadata; - private _native_scripts; - private _plutus_scripts_v1; - private _plutus_scripts_v2; - private _plutus_scripts_v3; - constructor(metadata: GeneralTransactionMetadata, native_scripts: NativeScripts, plutus_scripts_v1: PlutusScripts, plutus_scripts_v2: PlutusScripts, plutus_scripts_v3: PlutusScripts); - metadata(): GeneralTransactionMetadata; - set_metadata(metadata: GeneralTransactionMetadata): void; - native_scripts(): NativeScripts; - set_native_scripts(native_scripts: NativeScripts): void; - plutus_scripts_v1(): PlutusScripts; - set_plutus_scripts_v1(plutus_scripts_v1: PlutusScripts): void; - plutus_scripts_v2(): PlutusScripts; - set_plutus_scripts_v2(plutus_scripts_v2: PlutusScripts): void; - plutus_scripts_v3(): PlutusScripts; - set_plutus_scripts_v3(plutus_scripts_v3: PlutusScripts): void; + private variant; + constructor(variant: AuxiliaryDataVariant); + static new_shelley_metadata(shelley_metadata: GeneralTransactionMetadata): AuxiliaryData; + static new_shelley_metadata_ma(shelley_metadata_ma: AuxiliaryDataShelleyMa): AuxiliaryData; + static new_postalonzo_metadata(postalonzo_metadata: AuxiliaryDataPostAlonzo): AuxiliaryData; + as_shelley_metadata(): GeneralTransactionMetadata; + as_shelley_metadata_ma(): AuxiliaryDataShelleyMa; + as_postalonzo_metadata(): AuxiliaryDataPostAlonzo; + kind(): AuxiliaryDataKind; static deserialize(reader: CBORReader, path: string[]): AuxiliaryData; serialize(writer: CBORWriter): void; free(): void; @@ -125,6 +134,35 @@ export declare class AuxiliaryDataHash { static deserialize(reader: CBORReader, path: string[]): AuxiliaryDataHash; serialize(writer: CBORWriter): void; } +export declare class AuxiliaryDataPostAlonzo { + private _metadata; + private _native_scripts; + private _plutus_scripts_v1; + private _plutus_scripts_v2; + private _plutus_scripts_v3; + constructor(metadata: GeneralTransactionMetadata | undefined, native_scripts: NativeScripts | undefined, plutus_scripts_v1: PlutusScripts | undefined, plutus_scripts_v2: PlutusScripts | undefined, plutus_scripts_v3: PlutusScripts | undefined); + static new(metadata: GeneralTransactionMetadata | undefined, native_scripts: NativeScripts | undefined, plutus_scripts_v1: PlutusScripts | undefined, plutus_scripts_v2: PlutusScripts | undefined, plutus_scripts_v3: PlutusScripts | undefined): AuxiliaryDataPostAlonzo; + metadata(): GeneralTransactionMetadata | undefined; + set_metadata(metadata: GeneralTransactionMetadata | undefined): void; + native_scripts(): NativeScripts | undefined; + set_native_scripts(native_scripts: NativeScripts | undefined): void; + plutus_scripts_v1(): PlutusScripts | undefined; + set_plutus_scripts_v1(plutus_scripts_v1: PlutusScripts | undefined): void; + plutus_scripts_v2(): PlutusScripts | undefined; + set_plutus_scripts_v2(plutus_scripts_v2: PlutusScripts | undefined): void; + plutus_scripts_v3(): PlutusScripts | undefined; + set_plutus_scripts_v3(plutus_scripts_v3: PlutusScripts | undefined): void; + static deserialize(reader: CBORReader, path?: string[]): AuxiliaryDataPostAlonzo; + static deserializeInner(reader: CBORReader, path: string[]): AuxiliaryDataPostAlonzo; + serialize(writer: CBORWriter): void; + serializeInner(writer: CBORWriter): void; + free(): void; + static from_bytes(data: Uint8Array, path?: string[]): AuxiliaryDataPostAlonzo; + static from_hex(hex_str: string, path?: string[]): AuxiliaryDataPostAlonzo; + to_bytes(): Uint8Array; + to_hex(): string; + clone(path: string[]): AuxiliaryDataPostAlonzo; +} export declare class AuxiliaryDataSet { _items: [number, AuxiliaryData][]; constructor(items: [number, AuxiliaryData][]); @@ -143,6 +181,24 @@ export declare class AuxiliaryDataSet { clone(path: string[]): AuxiliaryDataSet; indices(): Uint32Array; } +export declare class AuxiliaryDataShelleyMa { + private _transaction_metadata; + private _auxiliary_scripts; + constructor(transaction_metadata: GeneralTransactionMetadata, auxiliary_scripts: NativeScripts); + static new(transaction_metadata: GeneralTransactionMetadata, auxiliary_scripts: NativeScripts): AuxiliaryDataShelleyMa; + transaction_metadata(): GeneralTransactionMetadata; + set_transaction_metadata(transaction_metadata: GeneralTransactionMetadata): void; + auxiliary_scripts(): NativeScripts; + set_auxiliary_scripts(auxiliary_scripts: NativeScripts): void; + static deserialize(reader: CBORReader, path: string[]): AuxiliaryDataShelleyMa; + serialize(writer: CBORWriter): void; + free(): void; + static from_bytes(data: Uint8Array, path?: string[]): AuxiliaryDataShelleyMa; + static from_hex(hex_str: string, path?: string[]): AuxiliaryDataShelleyMa; + to_bytes(): Uint8Array; + to_hex(): string; + clone(path: string[]): AuxiliaryDataShelleyMa; +} export declare class BigNum { private inner; constructor(inner: bigint); @@ -222,9 +278,8 @@ export declare class Block { private _transaction_bodies; private _transaction_witness_sets; private _auxiliary_data_set; - private _invalid_transactions; - constructor(header: Header, transaction_bodies: TransactionBodies, transaction_witness_sets: TransactionWitnessSets, auxiliary_data_set: AuxiliaryDataSet, invalid_transactions: Uint32Array); - static new(header: Header, transaction_bodies: TransactionBodies, transaction_witness_sets: TransactionWitnessSets, auxiliary_data_set: AuxiliaryDataSet, invalid_transactions: Uint32Array): Block; + private _inner_invalid_transactions; + constructor(header: Header, transaction_bodies: TransactionBodies, transaction_witness_sets: TransactionWitnessSets, auxiliary_data_set: AuxiliaryDataSet, inner_invalid_transactions: InvalidTransactions); header(): Header; set_header(header: Header): void; transaction_bodies(): TransactionBodies; @@ -233,8 +288,8 @@ export declare class Block { set_transaction_witness_sets(transaction_witness_sets: TransactionWitnessSets): void; auxiliary_data_set(): AuxiliaryDataSet; set_auxiliary_data_set(auxiliary_data_set: AuxiliaryDataSet): void; - invalid_transactions(): Uint32Array; - set_invalid_transactions(invalid_transactions: Uint32Array): void; + inner_invalid_transactions(): InvalidTransactions; + set_inner_invalid_transactions(inner_invalid_transactions: InvalidTransactions): void; static deserialize(reader: CBORReader, path: string[]): Block; serialize(writer: CBORWriter): void; free(): void; @@ -243,6 +298,9 @@ export declare class Block { to_bytes(): Uint8Array; to_hex(): string; clone(path: string[]): Block; + static new(header: Header, transaction_bodies: TransactionBodies, transaction_witness_sets: TransactionWitnessSets, auxiliary_data_set: AuxiliaryDataSet, invalid_transactions: Uint32Array): Block; + invalid_transactions(): Uint32Array; + set_invalid_transactions(invalid_transactions: Uint32Array): void; } export declare class BlockHash { private inner; @@ -285,11 +343,15 @@ export declare class BootstrapWitness { } export declare class BootstrapWitnesses { private items; - constructor(items: BootstrapWitness[]); + private definiteEncoding; + private nonEmptyTag; + private setItems; + constructor(definiteEncoding?: boolean, nonEmptyTag?: boolean); static new(): BootstrapWitnesses; len(): number; get(index: number): BootstrapWitness; - add(elem: BootstrapWitness): void; + add(elem: BootstrapWitness): boolean; + contains(elem: BootstrapWitness): boolean; static deserialize(reader: CBORReader, path: string[]): BootstrapWitnesses; serialize(writer: CBORWriter): void; free(): void; @@ -450,7 +512,10 @@ export declare class Certificate { } export declare class Certificates { private items; - constructor(); + private definiteEncoding; + private nonEmptyTag; + private setItems; + constructor(definiteEncoding?: boolean, nonEmptyTag?: boolean); static new(): Certificates; len(): number; get(index: number): Certificate; @@ -574,23 +639,27 @@ export declare class ConstrPlutusData { private _alternative; private _data; constructor(alternative: BigNum, data: PlutusList); - static new(alternative: BigNum, data: PlutusList): ConstrPlutusData; + static uncheckedNew(alternative: BigNum, data: PlutusList): ConstrPlutusData; alternative(): BigNum; set_alternative(alternative: BigNum): void; data(): PlutusList; set_data(data: PlutusList): void; - static deserialize(reader: CBORReader, path: string[]): ConstrPlutusData; - serialize(writer: CBORWriter): void; + static deserializeWithSeparateIdx(reader: CBORReader, path: string[]): ConstrPlutusData; + serializeWithSeparateIdx(writer: CBORWriter): void; free(): void; static from_bytes(data: Uint8Array, path?: string[]): ConstrPlutusData; static from_hex(hex_str: string, path?: string[]): ConstrPlutusData; to_bytes(): Uint8Array; to_hex(): string; clone(path: string[]): ConstrPlutusData; + static deserialize(reader: CBORReader, path: string[]): ConstrPlutusData; + serialize(writer: CBORWriter): void; + static new(alternative: BigNum, data: PlutusList): ConstrPlutusData; } export declare class CostModel { private items; - constructor(items: Int[]); + private definiteEncoding; + constructor(items: Int[], definiteEncoding?: boolean); static new(): CostModel; len(): number; get(index: number): Int; @@ -626,7 +695,10 @@ export declare class Costmdls { } export declare class Credentials { private items; - constructor(); + private definiteEncoding; + private nonEmptyTag; + private setItems; + constructor(definiteEncoding?: boolean, nonEmptyTag?: boolean); static new(): Credentials; len(): number; get(index: number): Credential; @@ -804,6 +876,22 @@ export declare class DRepVotingThresholds { to_hex(): string; clone(path: string[]): DRepVotingThresholds; } +export declare class Data { + private inner; + constructor(inner: Uint8Array); + static new(inner: Uint8Array): Data; + encoded_plutus_data(): Uint8Array; + static deserialize(reader: CBORReader, path?: string[]): Data; + static deserializeInner(reader: CBORReader, path: string[]): Data; + serialize(writer: CBORWriter): void; + serializeInner(writer: CBORWriter): void; + free(): void; + static from_bytes(data: Uint8Array, path?: string[]): Data; + static from_hex(hex_str: string, path?: string[]): Data; + to_bytes(): Uint8Array; + to_hex(): string; + clone(path: string[]): Data; +} export declare class DataCost { private _coins_per_byte; constructor(coins_per_byte: BigNum); @@ -836,22 +924,22 @@ export declare class DataHash { } export declare enum DataOptionKind { DataHash = 0, - PlutusData = 1 + Data = 1 } export type DataOptionVariant = { kind: 0; value: DataHash; } | { kind: 1; - value: PlutusData; + value: Data; }; export declare class DataOption { private variant; constructor(variant: DataOptionVariant); static new_hash(hash: DataHash): DataOption; - static new_data(data: PlutusData): DataOption; + static new_data(data: Data): DataOption; as_hash(): DataHash | undefined; - as_data(): PlutusData | undefined; + as_data(): Data | undefined; kind(): DataOptionKind; static deserialize(reader: CBORReader, path: string[]): DataOption; serialize(writer: CBORWriter): void; @@ -908,7 +996,10 @@ export declare class Ed25519KeyHash { } export declare class Ed25519KeyHashes { private items; - constructor(); + private definiteEncoding; + private nonEmptyTag; + private setItems; + constructor(definiteEncoding?: boolean, nonEmptyTag?: boolean); static new(): Ed25519KeyHashes; len(): number; get(index: number): Ed25519KeyHash; @@ -1025,7 +1116,8 @@ export declare class GenesisHash { } export declare class GenesisHashes { private items; - constructor(items: GenesisHash[]); + private definiteEncoding; + constructor(items: GenesisHash[], definiteEncoding?: boolean); static new(): GenesisHashes; len(): number; get(index: number): GenesisHash; @@ -1117,7 +1209,8 @@ export declare class GovernanceActionId { } export declare class GovernanceActionIds { private items; - constructor(items: GovernanceActionId[]); + private definiteEncoding; + constructor(items: GovernanceActionId[], definiteEncoding?: boolean); static new(): GovernanceActionIds; len(): number; get(index: number): GovernanceActionId; @@ -1268,6 +1361,22 @@ export declare class Int { as_i32_or_nothing(): number | undefined; as_i32_or_fail(): number; } +export declare class InvalidTransactions { + private items; + private definiteEncoding; + constructor(items: Uint32Array, definiteEncoding?: boolean); + static new(): InvalidTransactions; + len(): number; + static deserialize(reader: CBORReader, path: string[]): InvalidTransactions; + serialize(writer: CBORWriter): void; + free(): void; + static from_bytes(data: Uint8Array, path?: string[]): InvalidTransactions; + static from_hex(hex_str: string, path?: string[]): InvalidTransactions; + to_bytes(): Uint8Array; + to_hex(): string; + clone(path: string[]): InvalidTransactions; + as_uint32Array(): Uint32Array; +} export declare class Ipv4 { private inner; constructor(inner: Uint8Array); @@ -1348,7 +1457,8 @@ export declare class Language { } export declare class Languages { private items; - constructor(items: Language[]); + private definiteEncoding; + constructor(items: Language[], definiteEncoding?: boolean); static new(): Languages; len(): number; get(index: number): Language; @@ -1365,7 +1475,8 @@ export declare class Languages { } export declare class MetadataList { private items; - constructor(items: TransactionMetadatum[]); + private definiteEncoding; + constructor(items: TransactionMetadatum[], definiteEncoding?: boolean); static new(): MetadataList; len(): number; get(index: number): TransactionMetadatum; @@ -1444,7 +1555,8 @@ export declare class MintAssets { } export declare class MintsAssets { private items; - constructor(items: MintAssets[]); + private definiteEncoding; + constructor(items: MintAssets[], definiteEncoding?: boolean); static new(): MintsAssets; len(): number; get(index: number): MintAssets; @@ -1605,11 +1717,15 @@ export declare class NativeScriptSource { } export declare class NativeScripts { private items; - constructor(items: NativeScript[]); + private definiteEncoding; + private nonEmptyTag; + private setItems; + constructor(definiteEncoding?: boolean, nonEmptyTag?: boolean); static new(): NativeScripts; len(): number; get(index: number): NativeScript; - add(elem: NativeScript): void; + add(elem: NativeScript): boolean; + contains(elem: NativeScript): boolean; static deserialize(reader: CBORReader, path: string[]): NativeScripts; serialize(writer: CBORWriter): void; free(): void; @@ -1818,12 +1934,12 @@ export declare class PlutusData { } export declare class PlutusList { private items; - constructor(); + private definiteEncoding; + constructor(items: PlutusData[], definiteEncoding?: boolean); static new(): PlutusList; len(): number; get(index: number): PlutusData; - add(elem: PlutusData): boolean; - contains(elem: PlutusData): boolean; + add(elem: PlutusData): void; static deserialize(reader: CBORReader, path: string[]): PlutusList; serialize(writer: CBORWriter): void; free(): void; @@ -1832,6 +1948,7 @@ export declare class PlutusList { to_bytes(): Uint8Array; to_hex(): string; clone(path: string[]): PlutusList; + as_set(): PlutusSet; } export declare class PlutusMap { _items: [PlutusData, PlutusMapValues][]; @@ -1853,7 +1970,8 @@ export declare class PlutusMap { } export declare class PlutusMapValues { private items; - constructor(items: PlutusData[]); + private definiteEncoding; + constructor(items: PlutusData[], definiteEncoding?: boolean); static new(): PlutusMapValues; len(): number; get(index: number): PlutusData; @@ -1884,11 +2002,15 @@ export declare class PlutusScript { } export declare class PlutusScripts { private items; - constructor(items: PlutusScript[]); + private definiteEncoding; + private nonEmptyTag; + private setItems; + constructor(definiteEncoding?: boolean, nonEmptyTag?: boolean); static new(): PlutusScripts; len(): number; get(index: number): PlutusScript; - add(elem: PlutusScript): void; + add(elem: PlutusScript): boolean; + contains(elem: PlutusScript): boolean; static deserialize(reader: CBORReader, path: string[]): PlutusScripts; serialize(writer: CBORWriter): void; free(): void; @@ -1898,6 +2020,27 @@ export declare class PlutusScripts { to_hex(): string; clone(path: string[]): PlutusScripts; } +export declare class PlutusSet { + private items; + private definiteEncoding; + private nonEmptyTag; + private setItems; + constructor(definiteEncoding?: boolean, nonEmptyTag?: boolean); + static new(): PlutusSet; + len(): number; + get(index: number): PlutusData; + add(elem: PlutusData): boolean; + contains(elem: PlutusData): boolean; + static deserialize(reader: CBORReader, path: string[]): PlutusSet; + serialize(writer: CBORWriter): void; + free(): void; + static from_bytes(data: Uint8Array, path?: string[]): PlutusSet; + static from_hex(hex_str: string, path?: string[]): PlutusSet; + to_bytes(): Uint8Array; + to_hex(): string; + clone(path: string[]): PlutusSet; + as_list(): PlutusList; +} export declare class PoolMetadata { private _url; private _pool_metadata_hash; @@ -2030,6 +2173,51 @@ export declare class PoolVotingThresholds { to_hex(): string; clone(path: string[]): PoolVotingThresholds; } +export declare class PostAlonzoTransactionOutput { + private _address; + private _amount; + private _datum_option; + private _script_ref; + constructor(address: Address, amount: Value, datum_option: DataOption | undefined, script_ref: ScriptRef | undefined); + static new(address: Address, amount: Value, datum_option: DataOption | undefined, script_ref: ScriptRef | undefined): PostAlonzoTransactionOutput; + address(): Address; + set_address(address: Address): void; + amount(): Value; + set_amount(amount: Value): void; + datum_option(): DataOption | undefined; + set_datum_option(datum_option: DataOption | undefined): void; + script_ref(): ScriptRef | undefined; + set_script_ref(script_ref: ScriptRef | undefined): void; + static deserialize(reader: CBORReader, path: string[]): PostAlonzoTransactionOutput; + serialize(writer: CBORWriter): void; + free(): void; + static from_bytes(data: Uint8Array, path?: string[]): PostAlonzoTransactionOutput; + static from_hex(hex_str: string, path?: string[]): PostAlonzoTransactionOutput; + to_bytes(): Uint8Array; + to_hex(): string; + clone(path: string[]): PostAlonzoTransactionOutput; +} +export declare class PreBabbageTransactionOutput { + private _address; + private _amount; + private _datum_hash; + constructor(address: Address, amount: Value, datum_hash: DataHash | undefined); + static new(address: Address, amount: Value, datum_hash: DataHash | undefined): PreBabbageTransactionOutput; + address(): Address; + set_address(address: Address): void; + amount(): Value; + set_amount(amount: Value): void; + datum_hash(): DataHash | undefined; + set_datum_hash(datum_hash: DataHash | undefined): void; + static deserialize(reader: CBORReader, path: string[]): PreBabbageTransactionOutput; + serialize(writer: CBORWriter): void; + free(): void; + static from_bytes(data: Uint8Array, path?: string[]): PreBabbageTransactionOutput; + static from_hex(hex_str: string, path?: string[]): PreBabbageTransactionOutput; + to_bytes(): Uint8Array; + to_hex(): string; + clone(path: string[]): PreBabbageTransactionOutput; +} export declare class PrivateKey { private inner; private options?; @@ -2214,20 +2402,9 @@ export declare class PublicKey { to_bech32(): void; } export declare class Redeemer { - private _tag; - private _index; - private _data; - private _ex_units; - constructor(tag: RedeemerTag, index: BigNum, data: PlutusData, ex_units: ExUnits); - static new(tag: RedeemerTag, index: BigNum, data: PlutusData, ex_units: ExUnits): Redeemer; - tag(): RedeemerTag; - set_tag(tag: RedeemerTag): void; - index(): BigNum; - set_index(index: BigNum): void; - data(): PlutusData; - set_data(data: PlutusData): void; - ex_units(): ExUnits; - set_ex_units(ex_units: ExUnits): void; + private inner; + constructor(inner: RedeemersArrayItem); + redeemerArrayItem(): RedeemersArrayItem; static deserialize(reader: CBORReader, path: string[]): Redeemer; serialize(writer: CBORWriter): void; free(): void; @@ -2236,6 +2413,7 @@ export declare class Redeemer { to_bytes(): Uint8Array; to_hex(): string; clone(path: string[]): Redeemer; + static new(tag: RedeemerTag, index: BigNum, data: PlutusData, ex_units: ExUnits): Redeemer; } export declare enum RedeemerTagKind { spending = 0, @@ -2264,13 +2442,27 @@ export declare class RedeemerTag { to_hex(): string; clone(path: string[]): RedeemerTag; } +export declare enum RedeemersKind { + RedeemersArray = 0, + RedeemersMap = 1 +} +export type RedeemersVariant = { + kind: 0; + value: RedeemersArray; +} | { + kind: 1; + value: RedeemersMap; +}; export declare class Redeemers { - private items; - constructor(items: Redeemer[]); - static new(): Redeemers; - len(): number; - get(index: number): Redeemer; - add(elem: Redeemer): void; + private variant; + constructor(variant: RedeemersVariant); + static new_redeemers_array(redeemers_array: RedeemersArray): Redeemers; + static new_redeemers_map(redeemers_map: RedeemersMap): Redeemers; + as_redeemers_array(): RedeemersArray; + as_redeemers_map(): RedeemersMap; + kind(): RedeemersKind; + static deserialize(reader: CBORReader, path: string[]): Redeemers; + serialize(writer: CBORWriter): void; free(): void; static from_bytes(data: Uint8Array, path?: string[]): Redeemers; static from_hex(hex_str: string, path?: string[]): Redeemers; @@ -2278,10 +2470,27 @@ export declare class Redeemers { to_hex(): string; clone(path: string[]): Redeemers; total_ex_units(): ExUnits; - static deserialize(reader: CBORReader, path: string[]): Redeemers; - static deserializeArray(reader: CBORReader, path: string[]): Redeemers; - static deserializeMap(reader: CBORReader, path: string[]): Redeemers; + static new(): Redeemers; + len(): number; + add(elem: Redeemer): void; + get(index: number): Redeemer; +} +export declare class RedeemersArray { + private items; + private definiteEncoding; + constructor(items: RedeemersArrayItem[], definiteEncoding?: boolean); + static new(): RedeemersArray; + len(): number; + get(index: number): RedeemersArrayItem; + add(elem: RedeemersArrayItem): void; + static deserialize(reader: CBORReader, path: string[]): RedeemersArray; serialize(writer: CBORWriter): void; + free(): void; + static from_bytes(data: Uint8Array, path?: string[]): RedeemersArray; + static from_hex(hex_str: string, path?: string[]): RedeemersArray; + to_bytes(): Uint8Array; + to_hex(): string; + clone(path: string[]): RedeemersArray; } export declare class RedeemersArrayItem { private _tag; @@ -2325,6 +2534,41 @@ export declare class RedeemersKey { to_hex(): string; clone(path: string[]): RedeemersKey; } +export declare class RedeemersKeys { + private items; + private definiteEncoding; + constructor(items: RedeemersKey[], definiteEncoding?: boolean); + static new(): RedeemersKeys; + len(): number; + get(index: number): RedeemersKey; + add(elem: RedeemersKey): void; + static deserialize(reader: CBORReader, path: string[]): RedeemersKeys; + serialize(writer: CBORWriter): void; + free(): void; + static from_bytes(data: Uint8Array, path?: string[]): RedeemersKeys; + static from_hex(hex_str: string, path?: string[]): RedeemersKeys; + to_bytes(): Uint8Array; + to_hex(): string; + clone(path: string[]): RedeemersKeys; +} +export declare class RedeemersMap { + _items: [RedeemersKey, RedeemersValue][]; + constructor(items: [RedeemersKey, RedeemersValue][]); + static new(): RedeemersMap; + len(): number; + insert(key: RedeemersKey, value: RedeemersValue): RedeemersValue | undefined; + get(key: RedeemersKey): RedeemersValue | undefined; + _remove_many(keys: RedeemersKey[]): void; + keys(): RedeemersKeys; + static deserialize(reader: CBORReader, path: string[]): RedeemersMap; + serialize(writer: CBORWriter): void; + free(): void; + static from_bytes(data: Uint8Array, path?: string[]): RedeemersMap; + static from_hex(hex_str: string, path?: string[]): RedeemersMap; + to_bytes(): Uint8Array; + to_hex(): string; + clone(path: string[]): RedeemersMap; +} export declare class RedeemersValue { private _data; private _ex_units; @@ -2397,7 +2641,8 @@ export declare class Relay { } export declare class Relays { private items; - constructor(items: Relay[]); + private definiteEncoding; + constructor(items: Relay[], definiteEncoding?: boolean); static new(): Relays; len(): number; get(index: number): Relay; @@ -2413,7 +2658,8 @@ export declare class Relays { } export declare class RewardAddresses { private items; - constructor(items: RewardAddress[]); + private definiteEncoding; + constructor(items: RewardAddress[], definiteEncoding?: boolean); static new(): RewardAddresses; len(): number; get(index: number): RewardAddress; @@ -2489,7 +2735,8 @@ export declare class ScriptHash { } export declare class ScriptHashes { private items; - constructor(items: ScriptHash[]); + private definiteEncoding; + constructor(items: ScriptHash[], definiteEncoding?: boolean); static new(): ScriptHashes; len(): number; get(index: number): ScriptHash; @@ -2803,7 +3050,8 @@ export declare class Transaction { } export declare class TransactionBodies { private items; - constructor(items: TransactionBody[]); + private definiteEncoding; + constructor(items: TransactionBody[], definiteEncoding?: boolean); static new(): TransactionBodies; len(): number; get(index: number): TransactionBody; @@ -2929,7 +3177,10 @@ export declare class TransactionInput { } export declare class TransactionInputs { private items; - constructor(); + private definiteEncoding; + private nonEmptyTag; + private setItems; + constructor(definiteEncoding?: boolean, nonEmptyTag?: boolean); static new(): TransactionInputs; len(): number; get(index: number): TransactionInput; @@ -2992,7 +3243,8 @@ export declare class TransactionMetadatum { } export declare class TransactionMetadatumLabels { private items; - constructor(items: BigNum[]); + private definiteEncoding; + constructor(items: BigNum[], definiteEncoding?: boolean); static new(): TransactionMetadatumLabels; len(): number; get(index: number): BigNum; @@ -3006,20 +3258,25 @@ export declare class TransactionMetadatumLabels { to_hex(): string; clone(path: string[]): TransactionMetadatumLabels; } +export declare enum TransactionOutputKind { + PreBabbageTransactionOutput = 0, + PostAlonzoTransactionOutput = 1 +} +export type TransactionOutputVariant = { + kind: 0; + value: PreBabbageTransactionOutput; +} | { + kind: 1; + value: PostAlonzoTransactionOutput; +}; export declare class TransactionOutput { - private _address; - private _amount; - private _plutus_data; - private _script_ref; - constructor(address: Address, amount: Value, plutus_data: PlutusData | undefined, script_ref: ScriptRef | undefined); - address(): Address; - set_address(address: Address): void; - amount(): Value; - set_amount(amount: Value): void; - plutus_data(): PlutusData | undefined; - set_plutus_data(plutus_data: PlutusData | undefined): void; - script_ref(): ScriptRef | undefined; - set_script_ref(script_ref: ScriptRef | undefined): void; + private variant; + constructor(variant: TransactionOutputVariant); + static new_pre_babbage_transaction_output(pre_babbage_transaction_output: PreBabbageTransactionOutput): TransactionOutput; + static new_post_alonzo_transaction_output(post_alonzo_transaction_output: PostAlonzoTransactionOutput): TransactionOutput; + as_pre_babbage_transaction_output(): PreBabbageTransactionOutput; + as_post_alonzo_transaction_output(): PostAlonzoTransactionOutput; + kind(): TransactionOutputKind; static deserialize(reader: CBORReader, path: string[]): TransactionOutput; serialize(writer: CBORWriter): void; free(): void; @@ -3032,7 +3289,8 @@ export declare class TransactionOutput { } export declare class TransactionOutputs { private items; - constructor(items: TransactionOutput[]); + private definiteEncoding; + constructor(items: TransactionOutput[], definiteEncoding?: boolean); static new(): TransactionOutputs; len(): number; get(index: number): TransactionOutput; @@ -3051,11 +3309,11 @@ export declare class TransactionWitnessSet { private _native_scripts; private _bootstraps; private _plutus_scripts_v1; - private _plutus_data; + private _inner_plutus_data; private _redeemers; private _plutus_scripts_v2; private _plutus_scripts_v3; - constructor(vkeys: Vkeywitnesses | undefined, native_scripts: NativeScripts | undefined, bootstraps: BootstrapWitnesses | undefined, plutus_scripts_v1: PlutusScripts | undefined, plutus_data: PlutusList | undefined, redeemers: Redeemers | undefined, plutus_scripts_v2: PlutusScripts | undefined, plutus_scripts_v3: PlutusScripts | undefined); + constructor(vkeys: Vkeywitnesses | undefined, native_scripts: NativeScripts | undefined, bootstraps: BootstrapWitnesses | undefined, plutus_scripts_v1: PlutusScripts | undefined, inner_plutus_data: PlutusSet | undefined, redeemers: Redeemers | undefined, plutus_scripts_v2: PlutusScripts | undefined, plutus_scripts_v3: PlutusScripts | undefined); vkeys(): Vkeywitnesses | undefined; set_vkeys(vkeys: Vkeywitnesses | undefined): void; native_scripts(): NativeScripts | undefined; @@ -3064,8 +3322,8 @@ export declare class TransactionWitnessSet { set_bootstraps(bootstraps: BootstrapWitnesses | undefined): void; plutus_scripts_v1(): PlutusScripts | undefined; set_plutus_scripts_v1(plutus_scripts_v1: PlutusScripts | undefined): void; - plutus_data(): PlutusList | undefined; - set_plutus_data(plutus_data: PlutusList | undefined): void; + inner_plutus_data(): PlutusSet | undefined; + set_inner_plutus_data(inner_plutus_data: PlutusSet | undefined): void; redeemers(): Redeemers | undefined; set_redeemers(redeemers: Redeemers | undefined): void; plutus_scripts_v2(): PlutusScripts | undefined; @@ -3081,10 +3339,13 @@ export declare class TransactionWitnessSet { to_hex(): string; clone(path: string[]): TransactionWitnessSet; static new(): TransactionWitnessSet; + plutus_data(): PlutusList | undefined; + set_plutus_data(plutus_data: PlutusList): void; } export declare class TransactionWitnessSets { private items; - constructor(items: TransactionWitnessSet[]); + private definiteEncoding; + constructor(items: TransactionWitnessSet[], definiteEncoding?: boolean); static new(): TransactionWitnessSets; len(): number; get(index: number): TransactionWitnessSet; @@ -3309,18 +3570,19 @@ export declare class Vkey { static new(public_key: PublicKey): Vkey; public_key(): PublicKey; set_public_key(public_key: PublicKey): void; - static deserialize(reader: CBORReader, path: string[]): Vkey; - serialize(writer: CBORWriter): void; free(): void; static from_bytes(data: Uint8Array, path?: string[]): Vkey; static from_hex(hex_str: string, path?: string[]): Vkey; to_bytes(): Uint8Array; to_hex(): string; clone(path: string[]): Vkey; + static deserialize(reader: CBORReader, path: string[]): Vkey; + serialize(writer: CBORWriter): void; } export declare class Vkeys { private items; - constructor(items: Vkey[]); + private definiteEncoding; + constructor(items: Vkey[], definiteEncoding?: boolean); static new(): Vkeys; len(): number; get(index: number): Vkey; @@ -3354,7 +3616,10 @@ export declare class Vkeywitness { } export declare class Vkeywitnesses { private items; - constructor(); + private definiteEncoding; + private nonEmptyTag; + private setItems; + constructor(definiteEncoding?: boolean, nonEmptyTag?: boolean); static new(): Vkeywitnesses; len(): number; get(index: number): Vkeywitness; @@ -3469,7 +3734,8 @@ export declare class Voter { } export declare class Voters { private items; - constructor(items: Voter[]); + private definiteEncoding; + constructor(items: Voter[], definiteEncoding?: boolean); static new(): Voters; len(): number; get(index: number): Voter; @@ -3550,7 +3816,10 @@ export declare class VotingProposal { } export declare class VotingProposals { private items; - constructor(); + private definiteEncoding; + private nonEmptyTag; + private setItems; + constructor(definiteEncoding?: boolean, nonEmptyTag?: boolean); static new(): VotingProposals; len(): number; get(index: number): VotingProposal; @@ -3584,7 +3853,10 @@ export declare class Withdrawals { } export declare class certificates { private items; - constructor(); + private definiteEncoding; + private nonEmptyTag; + private setItems; + constructor(definiteEncoding?: boolean, nonEmptyTag?: boolean); static new(): certificates; len(): number; get(index: number): Certificate; @@ -3621,7 +3893,7 @@ export declare class ByronAddress { static deserializeInner(reader: CBORReader, path: string[]): ByronAddress; serialize(writer: CBORWriter): void; static deserialize(reader: CBORReader, path: string[]): ByronAddress; - static from_bytes(bytes: Uint8Array): ByronAddress; + static from_bytes(bytes: Uint8Array, path?: string[]): ByronAddress; to_bytes(): Uint8Array; byron_protocol_magic(): number; attributes(): Uint8Array; @@ -3720,7 +3992,7 @@ export declare class Address { is_malformed(): boolean; network_id(): number; to_bytes(): Uint8Array; - static from_bytes(bytes: Uint8Array): Address; + static from_bytes(bytes: Uint8Array, path: string[]): Address; serialize(writer: CBORWriter): void; static deserialize(reader: CBORReader, path: string[]): Address; } diff --git a/package-lock.json b/package-lock.json index 6e116a3..72fdfd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ }, "devDependencies": { "@blockfrost/blockfrost-js": "^5.5.0", - "@emurgo/cardano-serialization-lib-nodejs-gc": "^12.1", + "@emurgo/cardano-serialization-lib-nodejs-gc": "^13.0", "@jest/globals": "^29.5.13", "@ohm-js/cli": "^2.0.0", "@prettier/sync": "^0.5.2", @@ -693,9 +693,9 @@ } }, "node_modules/@emurgo/cardano-serialization-lib-nodejs-gc": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-nodejs-gc/-/cardano-serialization-lib-nodejs-gc-12.1.0.tgz", - "integrity": "sha512-2igQK7RxIfk9cw55bL4hWp19Z2dTBqzqEBa+0CebOhH6xmRo0mgSudjKyqvWuhZhjIsjvsOHHL7Rpb6gPT8eiA==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-nodejs-gc/-/cardano-serialization-lib-nodejs-gc-13.2.0.tgz", + "integrity": "sha512-027RaJYG1pdCmFMQueZgJnE87Lt8UCZMkTtY3YOQGgcWooyuYgCmANuic0itVpE8ojfOb4RgQ6ubNF6sh6+CdQ==", "dev": true }, "node_modules/@emurgo/cip14-js": { diff --git a/package.json b/package.json index e3e39d3..15cb6e3 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "type": "module", "devDependencies": { "@blockfrost/blockfrost-js": "^5.5.0", - "@emurgo/cardano-serialization-lib-nodejs-gc": "^12.1", + "@emurgo/cardano-serialization-lib-nodejs-gc": "^13.0", "@jest/globals": "^29.5.13", "@ohm-js/cli": "^2.0.0", "@prettier/sync": "^0.5.2", diff --git a/src/address/byron.ts b/src/address/byron.ts index 2b7d65f..b8e137e 100644 --- a/src/address/byron.ts +++ b/src/address/byron.ts @@ -65,16 +65,15 @@ export class ByronAddress { if (crc32 != calculatedCrc32) throw new Error(`Invalid CRC32 (at ${path.join("/")})`); - let bytes = new CBORReader(wrappedBytes).readBytes([...path, "0", "0"]); - return ByronAddress.deserializeInner(new CBORReader(bytes), [ + return ByronAddress.deserializeInner(new CBORReader(wrappedBytes), [ ...path, "0", "0", ]); } - static from_bytes(bytes: Uint8Array): ByronAddress { - return ByronAddress.deserialize(new CBORReader(bytes), []); + static from_bytes(bytes: Uint8Array, path: string[] = ["ByronAddress"]): ByronAddress { + return ByronAddress.deserialize(new CBORReader(bytes), path); } to_bytes(): Uint8Array { diff --git a/src/address/index.ts b/src/address/index.ts index 1bc94d4..a9848ef 100644 --- a/src/address/index.ts +++ b/src/address/index.ts @@ -107,7 +107,7 @@ export class Address { } } - static from_bytes(bytes: Uint8Array): Address { + static from_bytes(bytes: Uint8Array, path: string[]): Address { if (bytes.length < 1) { return new Address({ kind: AddressKind.Malformed, @@ -116,14 +116,14 @@ export class Address { } const header = bytes[0]; - switch (header & 0b1111) { + switch (header >> 4) { case 0b0000: case 0b0001: case 0b0010: - case 0b0011: + case 0b0011: return new Address({ - kind: AddressKind.Byron, - value: ByronAddress.from_bytes(bytes), + kind: AddressKind.Base, + value: BaseAddress.from_bytes(bytes) }); case 0b0110: case 0b0111: @@ -137,6 +137,11 @@ export class Address { kind: AddressKind.Reward, value: RewardAddress.from_bytes(bytes), }); + case 0b1000: + return new Address({ + kind: AddressKind.Byron, + value: ByronAddress.from_bytes(bytes, path), + }); default: return new Address({ kind: AddressKind.Malformed, @@ -150,6 +155,6 @@ export class Address { } static deserialize(reader: CBORReader, path: string[]): Address { - return Address.from_bytes(reader.readBytes(path)); + return Address.from_bytes(reader.readBytes(path), path); } } diff --git a/src/generated.ts b/src/generated.ts index 41d0f31..9d64b44 100644 --- a/src/generated.ts +++ b/src/generated.ts @@ -48,7 +48,7 @@ export class Anchor { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -68,7 +68,9 @@ export class Anchor { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._url.serialize(writer); this._anchor_data_hash.serialize(writer); @@ -216,9 +218,11 @@ export class AssetName { export class AssetNames { private items: AssetName[]; + private definiteEncoding: boolean; - constructor(items: AssetName[]) { + constructor(items: AssetName[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): AssetNames { @@ -239,17 +243,19 @@ export class AssetNames { } static deserialize(reader: CBORReader, path: string[]): AssetNames { - return new AssetNames( - reader.readArray( - (reader, idx) => - AssetName.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => AssetName.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new AssetNames(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -436,166 +442,123 @@ export class Assets { } } -export class AuxiliaryData { - private _metadata: GeneralTransactionMetadata; - private _native_scripts: NativeScripts; - private _plutus_scripts_v1: PlutusScripts; - private _plutus_scripts_v2: PlutusScripts; - private _plutus_scripts_v3: PlutusScripts; - - constructor( - metadata: GeneralTransactionMetadata, - native_scripts: NativeScripts, - plutus_scripts_v1: PlutusScripts, - plutus_scripts_v2: PlutusScripts, - plutus_scripts_v3: PlutusScripts, - ) { - this._metadata = metadata; - this._native_scripts = native_scripts; - this._plutus_scripts_v1 = plutus_scripts_v1; - this._plutus_scripts_v2 = plutus_scripts_v2; - this._plutus_scripts_v3 = plutus_scripts_v3; - } +export enum AuxiliaryDataKind { + GeneralTransactionMetadata = 0, + AuxiliaryDataShelleyMa = 1, + AuxiliaryDataPostAlonzo = 2, +} - metadata(): GeneralTransactionMetadata { - return this._metadata; - } +export type AuxiliaryDataVariant = + | { kind: 0; value: GeneralTransactionMetadata } + | { kind: 1; value: AuxiliaryDataShelleyMa } + | { kind: 2; value: AuxiliaryDataPostAlonzo }; - set_metadata(metadata: GeneralTransactionMetadata): void { - this._metadata = metadata; - } +export class AuxiliaryData { + private variant: AuxiliaryDataVariant; - native_scripts(): NativeScripts { - return this._native_scripts; + constructor(variant: AuxiliaryDataVariant) { + this.variant = variant; } - set_native_scripts(native_scripts: NativeScripts): void { - this._native_scripts = native_scripts; + static new_shelley_metadata( + shelley_metadata: GeneralTransactionMetadata, + ): AuxiliaryData { + return new AuxiliaryData({ kind: 0, value: shelley_metadata }); } - plutus_scripts_v1(): PlutusScripts { - return this._plutus_scripts_v1; + static new_shelley_metadata_ma( + shelley_metadata_ma: AuxiliaryDataShelleyMa, + ): AuxiliaryData { + return new AuxiliaryData({ kind: 1, value: shelley_metadata_ma }); } - set_plutus_scripts_v1(plutus_scripts_v1: PlutusScripts): void { - this._plutus_scripts_v1 = plutus_scripts_v1; + static new_postalonzo_metadata( + postalonzo_metadata: AuxiliaryDataPostAlonzo, + ): AuxiliaryData { + return new AuxiliaryData({ kind: 2, value: postalonzo_metadata }); } - plutus_scripts_v2(): PlutusScripts { - return this._plutus_scripts_v2; + as_shelley_metadata(): GeneralTransactionMetadata { + if (this.variant.kind == 0) return this.variant.value; + throw new Error("Incorrect cast"); } - set_plutus_scripts_v2(plutus_scripts_v2: PlutusScripts): void { - this._plutus_scripts_v2 = plutus_scripts_v2; + as_shelley_metadata_ma(): AuxiliaryDataShelleyMa { + if (this.variant.kind == 1) return this.variant.value; + throw new Error("Incorrect cast"); } - plutus_scripts_v3(): PlutusScripts { - return this._plutus_scripts_v3; + as_postalonzo_metadata(): AuxiliaryDataPostAlonzo { + if (this.variant.kind == 2) return this.variant.value; + throw new Error("Incorrect cast"); } - set_plutus_scripts_v3(plutus_scripts_v3: PlutusScripts): void { - this._plutus_scripts_v3 = plutus_scripts_v3; + kind(): AuxiliaryDataKind { + return this.variant.kind; } static deserialize(reader: CBORReader, path: string[]): AuxiliaryData { - let fields: any = {}; - reader.readMap((r) => { - let key = Number(r.readUint(path)); - switch (key) { - case 0: { - const new_path = [...path, "GeneralTransactionMetadata(metadata)"]; - fields.metadata = GeneralTransactionMetadata.deserialize(r, new_path); - break; - } - - case 1: { - const new_path = [...path, "NativeScripts(native_scripts)"]; - fields.native_scripts = NativeScripts.deserialize(r, new_path); - break; - } + let tag = reader.peekType(path); + let variant: AuxiliaryDataVariant; - case 2: { - const new_path = [...path, "PlutusScripts(plutus_scripts_v1)"]; - fields.plutus_scripts_v1 = PlutusScripts.deserialize(r, new_path); - break; - } + switch (tag) { + case "map": + variant = { + kind: AuxiliaryDataKind.GeneralTransactionMetadata, + value: GeneralTransactionMetadata.deserialize(reader, [ + ...path, + "GeneralTransactionMetadata(shelley_metadata)", + ]), + }; + break; - case 3: { - const new_path = [...path, "PlutusScripts(plutus_scripts_v2)"]; - fields.plutus_scripts_v2 = PlutusScripts.deserialize(r, new_path); - break; - } + case "array": + variant = { + kind: AuxiliaryDataKind.AuxiliaryDataShelleyMa, + value: AuxiliaryDataShelleyMa.deserialize(reader, [ + ...path, + "AuxiliaryDataShelleyMa(shelley_metadata_ma)", + ]), + }; + break; - case 4: { - const new_path = [...path, "PlutusScripts(plutus_scripts_v3)"]; - fields.plutus_scripts_v3 = PlutusScripts.deserialize(r, new_path); - break; - } - } - }, path); + case "tagged": + variant = { + kind: AuxiliaryDataKind.AuxiliaryDataPostAlonzo, + value: AuxiliaryDataPostAlonzo.deserialize(reader, [ + ...path, + "AuxiliaryDataPostAlonzo(postalonzo_metadata)", + ]), + }; + break; - if (fields.metadata === undefined) - throw new Error( - "Value not provided for field 0 (metadata) (at " + path.join("/") + ")", - ); - let metadata = fields.metadata; - if (fields.native_scripts === undefined) - throw new Error( - "Value not provided for field 1 (native_scripts) (at " + - path.join("/") + - ")", - ); - let native_scripts = fields.native_scripts; - if (fields.plutus_scripts_v1 === undefined) - throw new Error( - "Value not provided for field 2 (plutus_scripts_v1) (at " + - path.join("/") + - ")", - ); - let plutus_scripts_v1 = fields.plutus_scripts_v1; - if (fields.plutus_scripts_v2 === undefined) - throw new Error( - "Value not provided for field 3 (plutus_scripts_v2) (at " + - path.join("/") + - ")", - ); - let plutus_scripts_v2 = fields.plutus_scripts_v2; - if (fields.plutus_scripts_v3 === undefined) - throw new Error( - "Value not provided for field 4 (plutus_scripts_v3) (at " + - path.join("/") + - ")", - ); - let plutus_scripts_v3 = fields.plutus_scripts_v3; + default: + throw new Error( + "Unexpected subtype for AuxiliaryData: " + + tag + + "(at " + + path.join("/") + + ")", + ); + } - return new AuxiliaryData( - metadata, - native_scripts, - plutus_scripts_v1, - plutus_scripts_v2, - plutus_scripts_v3, - ); + return new AuxiliaryData(variant); } serialize(writer: CBORWriter): void { - let len = 5; - - writer.writeMapTag(len); - - writer.writeInt(0n); - this._metadata.serialize(writer); - - writer.writeInt(1n); - this._native_scripts.serialize(writer); - - writer.writeInt(2n); - this._plutus_scripts_v1.serialize(writer); + switch (this.variant.kind) { + case 0: + this.variant.value.serialize(writer); + break; - writer.writeInt(3n); - this._plutus_scripts_v2.serialize(writer); + case 1: + this.variant.value.serialize(writer); + break; - writer.writeInt(4n); - this._plutus_scripts_v3.serialize(writer); + case 2: + this.variant.value.serialize(writer); + break; + } } // no-op @@ -631,13 +594,14 @@ export class AuxiliaryData { } static new(): AuxiliaryData { - return new AuxiliaryData( + const post_alonzo_auxiliary_data = new AuxiliaryDataPostAlonzo( GeneralTransactionMetadata.new(), NativeScripts.new(), PlutusScripts.new(), PlutusScripts.new(), PlutusScripts.new(), ); + return new AuxiliaryData({ kind: 2, value: post_alonzo_auxiliary_data }); } } @@ -699,143 +663,208 @@ export class AuxiliaryDataHash { } } -export class AuxiliaryDataSet { - _items: [number, AuxiliaryData][]; +export class AuxiliaryDataPostAlonzo { + private _metadata: GeneralTransactionMetadata | undefined; + private _native_scripts: NativeScripts | undefined; + private _plutus_scripts_v1: PlutusScripts | undefined; + private _plutus_scripts_v2: PlutusScripts | undefined; + private _plutus_scripts_v3: PlutusScripts | undefined; - constructor(items: [number, AuxiliaryData][]) { - this._items = items; + constructor( + metadata: GeneralTransactionMetadata | undefined, + native_scripts: NativeScripts | undefined, + plutus_scripts_v1: PlutusScripts | undefined, + plutus_scripts_v2: PlutusScripts | undefined, + plutus_scripts_v3: PlutusScripts | undefined, + ) { + this._metadata = metadata; + this._native_scripts = native_scripts; + this._plutus_scripts_v1 = plutus_scripts_v1; + this._plutus_scripts_v2 = plutus_scripts_v2; + this._plutus_scripts_v3 = plutus_scripts_v3; } - static new(): AuxiliaryDataSet { - return new AuxiliaryDataSet([]); + static new( + metadata: GeneralTransactionMetadata | undefined, + native_scripts: NativeScripts | undefined, + plutus_scripts_v1: PlutusScripts | undefined, + plutus_scripts_v2: PlutusScripts | undefined, + plutus_scripts_v3: PlutusScripts | undefined, + ) { + return new AuxiliaryDataPostAlonzo( + metadata, + native_scripts, + plutus_scripts_v1, + plutus_scripts_v2, + plutus_scripts_v3, + ); } - len(): number { - return this._items.length; + metadata(): GeneralTransactionMetadata | undefined { + return this._metadata; } - insert(key: number, value: AuxiliaryData): AuxiliaryData | undefined { - let entry = this._items.find((x) => key === x[0]); - if (entry != null) { - let ret = entry[1]; - entry[1] = value; - return ret; - } - this._items.push([key, value]); - return undefined; + set_metadata(metadata: GeneralTransactionMetadata | undefined): void { + this._metadata = metadata; } - get(key: number): AuxiliaryData | undefined { - let entry = this._items.find((x) => key === x[0]); - if (entry == null) return undefined; - return entry[1]; + native_scripts(): NativeScripts | undefined { + return this._native_scripts; } - _remove_many(keys: number[]): void { - this._items = this._items.filter(([k, _v]) => - keys.every((key) => !(key === k)), - ); + set_native_scripts(native_scripts: NativeScripts | undefined): void { + this._native_scripts = native_scripts; } - static deserialize(reader: CBORReader, path: string[]): AuxiliaryDataSet { - let ret = new AuxiliaryDataSet([]); - reader.readMap( - (reader, idx) => - ret.insert( - Number(reader.readInt([...path, "number#" + idx])), - AuxiliaryData.deserialize(reader, [...path, "AuxiliaryData#" + idx]), - ), - path, - ); - return ret; + plutus_scripts_v1(): PlutusScripts | undefined { + return this._plutus_scripts_v1; } - serialize(writer: CBORWriter): void { - writer.writeMap(this._items, (writer, x) => { - writer.writeInt(BigInt(x[0])); - x[1].serialize(writer); - }); + set_plutus_scripts_v1(plutus_scripts_v1: PlutusScripts | undefined): void { + this._plutus_scripts_v1 = plutus_scripts_v1; } - // no-op - free(): void {} - - static from_bytes( - data: Uint8Array, - path: string[] = ["AuxiliaryDataSet"], - ): AuxiliaryDataSet { - let reader = new CBORReader(data); - return AuxiliaryDataSet.deserialize(reader, path); + plutus_scripts_v2(): PlutusScripts | undefined { + return this._plutus_scripts_v2; } - static from_hex( - hex_str: string, - path: string[] = ["AuxiliaryDataSet"], - ): AuxiliaryDataSet { - return AuxiliaryDataSet.from_bytes(hexToBytes(hex_str), path); + set_plutus_scripts_v2(plutus_scripts_v2: PlutusScripts | undefined): void { + this._plutus_scripts_v2 = plutus_scripts_v2; } - to_bytes(): Uint8Array { - let writer = new CBORWriter(); - this.serialize(writer); - return writer.getBytes(); + plutus_scripts_v3(): PlutusScripts | undefined { + return this._plutus_scripts_v3; } - to_hex(): string { - return bytesToHex(this.to_bytes()); - } - - clone(path: string[]): AuxiliaryDataSet { - return AuxiliaryDataSet.from_bytes(this.to_bytes(), path); + set_plutus_scripts_v3(plutus_scripts_v3: PlutusScripts | undefined): void { + this._plutus_scripts_v3 = plutus_scripts_v3; } - indices(): Uint32Array { - let indices = new Uint32Array(this._items.length); - for (let i = 0; i < this._items.length; i++) { - let item = this._items[i]; - let key = item[0]; - indices[i] = key; + static deserialize( + reader: CBORReader, + path: string[] = ["AuxiliaryDataPostAlonzo"], + ): AuxiliaryDataPostAlonzo { + let taggedTag = reader.readTaggedTag(path); + if (taggedTag != 259) { + throw new Error( + "Expected tag 259, got " + taggedTag + " (at " + path + ")", + ); } - return indices; + + return AuxiliaryDataPostAlonzo.deserializeInner(reader, path); } -} -export class BigNum { - private inner: bigint; + static deserializeInner( + reader: CBORReader, + path: string[], + ): AuxiliaryDataPostAlonzo { + let fields: any = {}; + reader.readMap((r) => { + let key = Number(r.readUint(path)); + switch (key) { + case 0: { + const new_path = [...path, "GeneralTransactionMetadata(metadata)"]; + fields.metadata = GeneralTransactionMetadata.deserialize(r, new_path); + break; + } - constructor(inner: bigint) { - if (inner < 0n) throw new Error("Expected value to be atleast 0n"); - if (inner > BigNum._maxU64()) - throw new Error("Expected value to be atmost BigNum._maxU64()"); - this.inner = inner; - } + case 1: { + const new_path = [...path, "NativeScripts(native_scripts)"]; + fields.native_scripts = NativeScripts.deserialize(r, new_path); + break; + } - static new(inner: bigint): BigNum { - return new BigNum(inner); - } + case 2: { + const new_path = [...path, "PlutusScripts(plutus_scripts_v1)"]; + fields.plutus_scripts_v1 = PlutusScripts.deserialize(r, new_path); + break; + } - toJsValue(): bigint { - return this.inner; - } + case 3: { + const new_path = [...path, "PlutusScripts(plutus_scripts_v2)"]; + fields.plutus_scripts_v2 = PlutusScripts.deserialize(r, new_path); + break; + } - static deserialize(reader: CBORReader, path: string[]): BigNum { - return new BigNum(reader.readInt(path)); + case 4: { + const new_path = [...path, "PlutusScripts(plutus_scripts_v3)"]; + fields.plutus_scripts_v3 = PlutusScripts.deserialize(r, new_path); + break; + } + } + }, path); + + let metadata = fields.metadata; + + let native_scripts = fields.native_scripts; + + let plutus_scripts_v1 = fields.plutus_scripts_v1; + + let plutus_scripts_v2 = fields.plutus_scripts_v2; + + let plutus_scripts_v3 = fields.plutus_scripts_v3; + + return new AuxiliaryDataPostAlonzo( + metadata, + native_scripts, + plutus_scripts_v1, + plutus_scripts_v2, + plutus_scripts_v3, + ); } serialize(writer: CBORWriter): void { - writer.writeInt(this.inner); + writer.writeTaggedTag(259); + + this.serializeInner(writer); + } + + serializeInner(writer: CBORWriter): void { + let len = 5; + if (this._metadata === undefined) len -= 1; + if (this._native_scripts === undefined) len -= 1; + if (this._plutus_scripts_v1 === undefined) len -= 1; + if (this._plutus_scripts_v2 === undefined) len -= 1; + if (this._plutus_scripts_v3 === undefined) len -= 1; + writer.writeMapTag(len); + if (this._metadata !== undefined) { + writer.writeInt(0n); + this._metadata.serialize(writer); + } + if (this._native_scripts !== undefined) { + writer.writeInt(1n); + this._native_scripts.serialize(writer); + } + if (this._plutus_scripts_v1 !== undefined) { + writer.writeInt(2n); + this._plutus_scripts_v1.serialize(writer); + } + if (this._plutus_scripts_v2 !== undefined) { + writer.writeInt(3n); + this._plutus_scripts_v2.serialize(writer); + } + if (this._plutus_scripts_v3 !== undefined) { + writer.writeInt(4n); + this._plutus_scripts_v3.serialize(writer); + } } // no-op free(): void {} - static from_bytes(data: Uint8Array, path: string[] = ["BigNum"]): BigNum { + static from_bytes( + data: Uint8Array, + path: string[] = ["AuxiliaryDataPostAlonzo"], + ): AuxiliaryDataPostAlonzo { let reader = new CBORReader(data); - return BigNum.deserialize(reader, path); + return AuxiliaryDataPostAlonzo.deserialize(reader, path); } - static from_hex(hex_str: string, path: string[] = ["BigNum"]): BigNum { - return BigNum.from_bytes(hexToBytes(hex_str), path); + static from_hex( + hex_str: string, + path: string[] = ["AuxiliaryDataPostAlonzo"], + ): AuxiliaryDataPostAlonzo { + return AuxiliaryDataPostAlonzo.from_bytes(hexToBytes(hex_str), path); } to_bytes(): Uint8Array { @@ -848,98 +877,344 @@ export class BigNum { return bytesToHex(this.to_bytes()); } - clone(path: string[]): BigNum { - return BigNum.from_bytes(this.to_bytes(), path); - } - - // Lifted from: https://doc.rust-lang.org/std/primitive.u64.html#associatedconstant.MAX - static _maxU64(): bigint { - return 18446744073709551615n; + clone(path: string[]): AuxiliaryDataPostAlonzo { + return AuxiliaryDataPostAlonzo.from_bytes(this.to_bytes(), path); } +} - static from_str(string: string): BigNum { - return new BigNum(BigInt(string)); - } +export class AuxiliaryDataSet { + _items: [number, AuxiliaryData][]; - to_str(): string { - return this.toJsValue().toString(); + constructor(items: [number, AuxiliaryData][]) { + this._items = items; } - static zero(): BigNum { - return new BigNum(0n); + static new(): AuxiliaryDataSet { + return new AuxiliaryDataSet([]); } - static one(): BigNum { - return new BigNum(1n); + len(): number { + return this._items.length; } - is_zero(): boolean { - return this.toJsValue() == 0n; + insert(key: number, value: AuxiliaryData): AuxiliaryData | undefined { + let entry = this._items.find((x) => key === x[0]); + if (entry != null) { + let ret = entry[1]; + entry[1] = value; + return ret; + } + this._items.push([key, value]); + return undefined; } - div_floor(other: BigNum): BigNum { - let res = this.toJsValue() / other.toJsValue(); - return new BigNum(res); + get(key: number): AuxiliaryData | undefined { + let entry = this._items.find((x) => key === x[0]); + if (entry == null) return undefined; + return entry[1]; } - checked_mul(other: BigNum): BigNum { - let res = this.toJsValue() * other.toJsValue(); - if (res > BigNum._maxU64()) throw new Error("BigNum.checked_mul overflow"); - return new BigNum(res); + _remove_many(keys: number[]): void { + this._items = this._items.filter(([k, _v]) => + keys.every((key) => !(key === k)), + ); } - checked_add(other: BigNum): BigNum { - let res = this.toJsValue() + other.toJsValue(); - if (res > BigNum._maxU64()) throw new Error("BigNum.checked_add overflow"); - return new BigNum(res); + static deserialize(reader: CBORReader, path: string[]): AuxiliaryDataSet { + let ret = new AuxiliaryDataSet([]); + reader.readMap( + (reader, idx) => + ret.insert( + Number(reader.readInt([...path, "number#" + idx])), + AuxiliaryData.deserialize(reader, [...path, "AuxiliaryData#" + idx]), + ), + path, + ); + return ret; } - checked_sub(other: BigNum): BigNum { - let res = this.toJsValue() - other.toJsValue(); - if (res < 0n) throw new Error("BigNum.checked_sub overflow"); - return new BigNum(res); + serialize(writer: CBORWriter): void { + writer.writeMap(this._items, (writer, x) => { + writer.writeInt(BigInt(x[0])); + x[1].serialize(writer); + }); } - clamped_sub(other: BigNum): BigNum { - let res = this.toJsValue() - other.toJsValue(); - if (res < 0n) res = 0n; - return new BigNum(res); - } + // no-op + free(): void {} - compare(rhs_value: BigNum): number { - if (this.toJsValue() < rhs_value.toJsValue()) return -1; - else if (this.toJsValue() == rhs_value.toJsValue()) return 0; - else return 1; + static from_bytes( + data: Uint8Array, + path: string[] = ["AuxiliaryDataSet"], + ): AuxiliaryDataSet { + let reader = new CBORReader(data); + return AuxiliaryDataSet.deserialize(reader, path); } - less_than(rhs_value: BigNum): boolean { - return this.toJsValue() < rhs_value.toJsValue(); + static from_hex( + hex_str: string, + path: string[] = ["AuxiliaryDataSet"], + ): AuxiliaryDataSet { + return AuxiliaryDataSet.from_bytes(hexToBytes(hex_str), path); } - static max_value(): BigNum { - return new BigNum(BigNum._maxU64()); + to_bytes(): Uint8Array { + let writer = new CBORWriter(); + this.serialize(writer); + return writer.getBytes(); } - static max(a: BigNum, b: BigNum): BigNum { - if (a.toJsValue() > b.toJsValue()) return a; - else return b; + to_hex(): string { + return bytesToHex(this.to_bytes()); } - static _from_number(x: number): BigNum { - return new BigNum(BigInt(x)); + clone(path: string[]): AuxiliaryDataSet { + return AuxiliaryDataSet.from_bytes(this.to_bytes(), path); } - _to_number(): number { - return Number(this.toJsValue); + indices(): Uint32Array { + let indices = new Uint32Array(this._items.length); + for (let i = 0; i < this._items.length; i++) { + let item = this._items[i]; + let key = item[0]; + indices[i] = key; + } + return indices; } } -export class Bip32PrivateKey { - private inner: Uint8Array; +export class AuxiliaryDataShelleyMa { + private _transaction_metadata: GeneralTransactionMetadata; + private _auxiliary_scripts: NativeScripts; - constructor(inner: Uint8Array) { - if (inner.length != 96) throw new Error("Expected length to be 96"); - this.inner = inner; + constructor( + transaction_metadata: GeneralTransactionMetadata, + auxiliary_scripts: NativeScripts, + ) { + this._transaction_metadata = transaction_metadata; + this._auxiliary_scripts = auxiliary_scripts; + } + + static new( + transaction_metadata: GeneralTransactionMetadata, + auxiliary_scripts: NativeScripts, + ) { + return new AuxiliaryDataShelleyMa(transaction_metadata, auxiliary_scripts); + } + + transaction_metadata(): GeneralTransactionMetadata { + return this._transaction_metadata; + } + + set_transaction_metadata( + transaction_metadata: GeneralTransactionMetadata, + ): void { + this._transaction_metadata = transaction_metadata; + } + + auxiliary_scripts(): NativeScripts { + return this._auxiliary_scripts; + } + + set_auxiliary_scripts(auxiliary_scripts: NativeScripts): void { + this._auxiliary_scripts = auxiliary_scripts; + } + + static deserialize( + reader: CBORReader, + path: string[], + ): AuxiliaryDataShelleyMa { + let transaction_metadata = GeneralTransactionMetadata.deserialize(reader, [ + ...path, + "transaction_metadata", + ]); + + let auxiliary_scripts = NativeScripts.deserialize(reader, [ + ...path, + "auxiliary_scripts", + ]); + + return new AuxiliaryDataShelleyMa(transaction_metadata, auxiliary_scripts); + } + + serialize(writer: CBORWriter): void { + this._transaction_metadata.serialize(writer); + this._auxiliary_scripts.serialize(writer); + } + + // no-op + free(): void {} + + static from_bytes( + data: Uint8Array, + path: string[] = ["AuxiliaryDataShelleyMa"], + ): AuxiliaryDataShelleyMa { + let reader = new CBORReader(data); + return AuxiliaryDataShelleyMa.deserialize(reader, path); + } + + static from_hex( + hex_str: string, + path: string[] = ["AuxiliaryDataShelleyMa"], + ): AuxiliaryDataShelleyMa { + return AuxiliaryDataShelleyMa.from_bytes(hexToBytes(hex_str), path); + } + + to_bytes(): Uint8Array { + let writer = new CBORWriter(); + this.serialize(writer); + return writer.getBytes(); + } + + to_hex(): string { + return bytesToHex(this.to_bytes()); + } + + clone(path: string[]): AuxiliaryDataShelleyMa { + return AuxiliaryDataShelleyMa.from_bytes(this.to_bytes(), path); + } +} + +export class BigNum { + private inner: bigint; + + constructor(inner: bigint) { + if (inner < 0n) throw new Error("Expected value to be atleast 0n"); + if (inner > BigNum._maxU64()) + throw new Error("Expected value to be atmost BigNum._maxU64()"); + this.inner = inner; + } + + static new(inner: bigint): BigNum { + return new BigNum(inner); + } + + toJsValue(): bigint { + return this.inner; + } + + static deserialize(reader: CBORReader, path: string[]): BigNum { + return new BigNum(reader.readInt(path)); + } + + serialize(writer: CBORWriter): void { + writer.writeInt(this.inner); + } + + // no-op + free(): void {} + + static from_bytes(data: Uint8Array, path: string[] = ["BigNum"]): BigNum { + let reader = new CBORReader(data); + return BigNum.deserialize(reader, path); + } + + static from_hex(hex_str: string, path: string[] = ["BigNum"]): BigNum { + return BigNum.from_bytes(hexToBytes(hex_str), path); + } + + to_bytes(): Uint8Array { + let writer = new CBORWriter(); + this.serialize(writer); + return writer.getBytes(); + } + + to_hex(): string { + return bytesToHex(this.to_bytes()); + } + + clone(path: string[]): BigNum { + return BigNum.from_bytes(this.to_bytes(), path); + } + + // Lifted from: https://doc.rust-lang.org/std/primitive.u64.html#associatedconstant.MAX + static _maxU64(): bigint { + return 18446744073709551615n; + } + + static from_str(string: string): BigNum { + return new BigNum(BigInt(string)); + } + + to_str(): string { + return this.toJsValue().toString(); + } + + static zero(): BigNum { + return new BigNum(0n); + } + + static one(): BigNum { + return new BigNum(1n); + } + + is_zero(): boolean { + return this.toJsValue() == 0n; + } + + div_floor(other: BigNum): BigNum { + let res = this.toJsValue() / other.toJsValue(); + return new BigNum(res); + } + + checked_mul(other: BigNum): BigNum { + let res = this.toJsValue() * other.toJsValue(); + if (res > BigNum._maxU64()) throw new Error("BigNum.checked_mul overflow"); + return new BigNum(res); + } + + checked_add(other: BigNum): BigNum { + let res = this.toJsValue() + other.toJsValue(); + if (res > BigNum._maxU64()) throw new Error("BigNum.checked_add overflow"); + return new BigNum(res); + } + + checked_sub(other: BigNum): BigNum { + let res = this.toJsValue() - other.toJsValue(); + if (res < 0n) throw new Error("BigNum.checked_sub overflow"); + return new BigNum(res); + } + + clamped_sub(other: BigNum): BigNum { + let res = this.toJsValue() - other.toJsValue(); + if (res < 0n) res = 0n; + return new BigNum(res); + } + + compare(rhs_value: BigNum): number { + if (this.toJsValue() < rhs_value.toJsValue()) return -1; + else if (this.toJsValue() == rhs_value.toJsValue()) return 0; + else return 1; + } + + less_than(rhs_value: BigNum): boolean { + return this.toJsValue() < rhs_value.toJsValue(); + } + + static max_value(): BigNum { + return new BigNum(BigNum._maxU64()); + } + + static max(a: BigNum, b: BigNum): BigNum { + if (a.toJsValue() > b.toJsValue()) return a; + else return b; + } + + static _from_number(x: number): BigNum { + return new BigNum(BigInt(x)); + } + + _to_number(): number { + return Number(this.toJsValue); + } +} + +export class Bip32PrivateKey { + private inner: Uint8Array; + + constructor(inner: Uint8Array) { + if (inner.length != 96) throw new Error("Expected length to be 96"); + this.inner = inner; } static new(inner: Uint8Array): Bip32PrivateKey { @@ -1156,36 +1431,20 @@ export class Block { private _transaction_bodies: TransactionBodies; private _transaction_witness_sets: TransactionWitnessSets; private _auxiliary_data_set: AuxiliaryDataSet; - private _invalid_transactions: Uint32Array; + private _inner_invalid_transactions: InvalidTransactions; constructor( header: Header, transaction_bodies: TransactionBodies, transaction_witness_sets: TransactionWitnessSets, auxiliary_data_set: AuxiliaryDataSet, - invalid_transactions: Uint32Array, + inner_invalid_transactions: InvalidTransactions, ) { this._header = header; this._transaction_bodies = transaction_bodies; this._transaction_witness_sets = transaction_witness_sets; this._auxiliary_data_set = auxiliary_data_set; - this._invalid_transactions = invalid_transactions; - } - - static new( - header: Header, - transaction_bodies: TransactionBodies, - transaction_witness_sets: TransactionWitnessSets, - auxiliary_data_set: AuxiliaryDataSet, - invalid_transactions: Uint32Array, - ) { - return new Block( - header, - transaction_bodies, - transaction_witness_sets, - auxiliary_data_set, - invalid_transactions, - ); + this._inner_invalid_transactions = inner_invalid_transactions; } header(): Header { @@ -1222,12 +1481,14 @@ export class Block { this._auxiliary_data_set = auxiliary_data_set; } - invalid_transactions(): Uint32Array { - return this._invalid_transactions; + inner_invalid_transactions(): InvalidTransactions { + return this._inner_invalid_transactions; } - set_invalid_transactions(invalid_transactions: Uint32Array): void { - this._invalid_transactions = invalid_transactions; + set_inner_invalid_transactions( + inner_invalid_transactions: InvalidTransactions, + ): void { + this._inner_invalid_transactions = inner_invalid_transactions; } static deserialize(reader: CBORReader, path: string[]): Block { @@ -1235,7 +1496,7 @@ export class Block { if (len != null && len < 5) { throw new Error( - "Insufficient number of fields in record. Expected 5. Received " + + "Insufficient number of fields in record. Expected at least 5. Received " + len + "(at " + path.join("/"), @@ -1272,15 +1533,13 @@ export class Block { auxiliary_data_set_path, ); - const invalid_transactions_path = [ + const inner_invalid_transactions_path = [ ...path, - "arrayToUint32Array(invalid_transactions)", + "InvalidTransactions(inner_invalid_transactions)", ]; - let invalid_transactions = new Uint32Array( - reader.readArray( - (reader) => Number(reader.readUint(invalid_transactions_path)), - invalid_transactions_path, - ), + let inner_invalid_transactions = InvalidTransactions.deserialize( + reader, + inner_invalid_transactions_path, ); return new Block( @@ -1288,20 +1547,20 @@ export class Block { transaction_bodies, transaction_witness_sets, auxiliary_data_set, - invalid_transactions, + inner_invalid_transactions, ); } serialize(writer: CBORWriter): void { - writer.writeArrayTag(5); + let arrayLen = 5; + + writer.writeArrayTag(arrayLen); this._header.serialize(writer); this._transaction_bodies.serialize(writer); this._transaction_witness_sets.serialize(writer); this._auxiliary_data_set.serialize(writer); - writer.writeArray(this._invalid_transactions, (writer, x) => - writer.writeInt(BigInt(x)), - ); + this._inner_invalid_transactions.serialize(writer); } // no-op @@ -1329,6 +1588,32 @@ export class Block { clone(path: string[]): Block { return Block.from_bytes(this.to_bytes(), path); } + + static new( + header: Header, + transaction_bodies: TransactionBodies, + transaction_witness_sets: TransactionWitnessSets, + auxiliary_data_set: AuxiliaryDataSet, + invalid_transactions: Uint32Array, + ): Block { + return new Block( + header, + transaction_bodies, + transaction_witness_sets, + auxiliary_data_set, + new InvalidTransactions(invalid_transactions), + ); + } + + invalid_transactions(): Uint32Array { + return this.inner_invalid_transactions().as_uint32Array(); + } + + set_invalid_transactions(invalid_transactions: Uint32Array) { + this._inner_invalid_transactions = new InvalidTransactions( + invalid_transactions, + ); + } } export class BlockHash { @@ -1453,7 +1738,7 @@ export class BootstrapWitness { if (len != null && len < 4) { throw new Error( - "Insufficient number of fields in record. Expected 4. Received " + + "Insufficient number of fields in record. Expected at least 4. Received " + len + "(at " + path.join("/"), @@ -1476,7 +1761,9 @@ export class BootstrapWitness { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(4); + let arrayLen = 4; + + writer.writeArrayTag(arrayLen); this._vkey.serialize(writer); this._signature.serialize(writer); @@ -1519,13 +1806,21 @@ export class BootstrapWitness { export class BootstrapWitnesses { private items: BootstrapWitness[]; + private definiteEncoding: boolean; + private nonEmptyTag: boolean; - constructor(items: BootstrapWitness[]) { + private setItems(items: BootstrapWitness[]) { this.items = items; } + constructor(definiteEncoding: boolean = true, nonEmptyTag: boolean = true) { + this.items = []; + this.definiteEncoding = definiteEncoding; + this.nonEmptyTag = nonEmptyTag; + } + static new(): BootstrapWitnesses { - return new BootstrapWitnesses([]); + return new BootstrapWitnesses(); } len(): number { @@ -1537,23 +1832,50 @@ export class BootstrapWitnesses { return this.items[index]; } - add(elem: BootstrapWitness): void { + add(elem: BootstrapWitness): boolean { + if (this.contains(elem)) return true; this.items.push(elem); + return false; } - static deserialize(reader: CBORReader, path: string[]): BootstrapWitnesses { - return new BootstrapWitnesses( - reader.readArray( - (reader, idx) => - BootstrapWitness.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), - ); + contains(elem: BootstrapWitness): boolean { + for (let item of this.items) { + if (arrayEq(item.to_bytes(), elem.to_bytes())) { + return true; + } + } + return false; } - serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); - } + static deserialize(reader: CBORReader, path: string[]): BootstrapWitnesses { + let nonEmptyTag = false; + if (reader.peekType(path) == "tagged") { + let tag = reader.readTaggedTag(path); + if (tag != 258) { + throw new Error("Expected tag 258. Got " + tag); + } else { + nonEmptyTag = true; + } + } + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + BootstrapWitness.deserialize(reader, [ + ...path, + "BootstrapWitness#" + idx, + ]), + path, + ); + let ret = new BootstrapWitnesses(definiteEncoding, nonEmptyTag); + ret.setItems(items); + return ret; + } + + serialize(writer: CBORWriter): void { + if (this.nonEmptyTag) { + writer.writeTaggedTag(258); + } + writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + } // no-op free(): void {} @@ -2237,15 +2559,22 @@ export class Certificate { }; break; + + default: + throw new Error( + "Unexpected tag for Certificate: " + + tag + + "(at " + + path.join("/") + + ")", + ); } if (len == null) { reader.readBreak(); } - throw new Error( - "Unexpected tag for Certificate: " + tag + "(at " + path.join("/") + ")", - ); + return new Certificate(variant); } serialize(writer: CBORWriter): void { @@ -2373,9 +2702,17 @@ export class Certificate { export class Certificates { private items: Certificate[]; + private definiteEncoding: boolean; + private nonEmptyTag: boolean; - constructor() { + private setItems(items: Certificate[]) { + this.items = items; + } + + constructor(definiteEncoding: boolean = true, nonEmptyTag: boolean = true) { this.items = []; + this.definiteEncoding = definiteEncoding; + this.nonEmptyTag = nonEmptyTag; } static new(): Certificates { @@ -2407,23 +2744,29 @@ export class Certificates { } static deserialize(reader: CBORReader, path: string[]): Certificates { - let ret = new Certificates(); + let nonEmptyTag = false; if (reader.peekType(path) == "tagged") { let tag = reader.readTaggedTag(path); - if (tag != 258) throw new Error("Expected tag 258. Got " + tag); + if (tag != 258) { + throw new Error("Expected tag 258. Got " + tag); + } else { + nonEmptyTag = true; + } } - reader.readArray( + const { items, definiteEncoding } = reader.readArray( (reader, idx) => - ret.add( - Certificate.deserialize(reader, [...path, "Certificate#" + idx]), - ), + Certificate.deserialize(reader, [...path, "Certificate#" + idx]), path, ); + let ret = new Certificates(definiteEncoding, nonEmptyTag); + ret.setItems(items); return ret; } serialize(writer: CBORWriter): void { - writer.writeTaggedTag(258); + if (this.nonEmptyTag) { + writer.writeTaggedTag(258); + } writer.writeArray(this.items, (writer, x) => x.serialize(writer)); } @@ -2504,7 +2847,7 @@ export class ChangeConfig { if (len != null && len < 3) { throw new Error( - "Insufficient number of fields in record. Expected 3. Received " + + "Insufficient number of fields in record. Expected at least 3. Received " + len + "(at " + path.join("/"), @@ -2532,7 +2875,9 @@ export class ChangeConfig { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(3); + let arrayLen = 3; + + writer.writeArrayTag(arrayLen); this._address.serialize(writer); if (this._plutus_data == null) { @@ -2934,7 +3279,7 @@ export class Constitution { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -2955,7 +3300,9 @@ export class Constitution { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._anchor.serialize(writer); if (this._scripthash == null) { @@ -3011,7 +3358,7 @@ export class ConstrPlutusData { this._data = data; } - static new(alternative: BigNum, data: PlutusList) { + static uncheckedNew(alternative: BigNum, data: PlutusList) { return new ConstrPlutusData(alternative, data); } @@ -3031,12 +3378,15 @@ export class ConstrPlutusData { this._data = data; } - static deserialize(reader: CBORReader, path: string[]): ConstrPlutusData { + static deserializeWithSeparateIdx( + reader: CBORReader, + path: string[], + ): ConstrPlutusData { let len = reader.readArrayTag(path); if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -3052,8 +3402,10 @@ export class ConstrPlutusData { return new ConstrPlutusData(alternative, data); } - serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + serializeWithSeparateIdx(writer: CBORWriter): void { + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._alternative.serialize(writer); this._data.serialize(writer); @@ -3090,13 +3442,56 @@ export class ConstrPlutusData { clone(path: string[]): ConstrPlutusData { return ConstrPlutusData.from_bytes(this.to_bytes(), path); } + + static deserialize(reader: CBORReader, path: string[]): ConstrPlutusData { + const alternative = reader.readTaggedTagAsBigInt(path); + if (Number(alternative) >= 121 && Number(alternative) <= 127) { + return ConstrPlutusData.new( + BigNum.new(alternative), + PlutusList.deserialize(reader, [...path, "PlutusList(data)"]), + ); + } else if (Number(alternative) == 102) { + return ConstrPlutusData.deserializeWithSeparateIdx(reader, path); + } else { + throw new Error( + "Unexpected alternative for ConstrPlutusData: " + + alternative + + "(at " + + path.join("/") + + ")", + ); + } + } + + serialize(writer: CBORWriter): void { + const alternative = this.alternative().toJsValue(); + writer.writeTaggedTag(Number(alternative)); + if (alternative == 102n) { + this.serializeWithSeparateIdx(writer); + } else { + this.data().serialize(writer); + } + } + + static new(alternative: BigNum, data: PlutusList): ConstrPlutusData { + const alt = Number(alternative.toJsValue()); + if (alt != 102 && (alt < 121 || alt > 127)) { + throw new Error( + "Unexpected alternative for ConstrPlutusData: " + alternative, + ); + } else { + return ConstrPlutusData.uncheckedNew(alternative, data); + } + } } export class CostModel { private items: Int[]; + private definiteEncoding: boolean; - constructor(items: Int[]) { + constructor(items: Int[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): CostModel { @@ -3117,16 +3512,19 @@ export class CostModel { } static deserialize(reader: CBORReader, path: string[]): CostModel { - return new CostModel( - reader.readArray( - (reader, idx) => Int.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => Int.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new CostModel(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -3286,9 +3684,17 @@ export class Costmdls { export class Credentials { private items: Credential[]; + private definiteEncoding: boolean; + private nonEmptyTag: boolean; - constructor() { + private setItems(items: Credential[]) { + this.items = items; + } + + constructor(definiteEncoding: boolean = true, nonEmptyTag: boolean = true) { this.items = []; + this.definiteEncoding = definiteEncoding; + this.nonEmptyTag = nonEmptyTag; } static new(): Credentials { @@ -3320,21 +3726,29 @@ export class Credentials { } static deserialize(reader: CBORReader, path: string[]): Credentials { - let ret = new Credentials(); + let nonEmptyTag = false; if (reader.peekType(path) == "tagged") { let tag = reader.readTaggedTag(path); - if (tag != 258) throw new Error("Expected tag 258. Got " + tag); + if (tag != 258) { + throw new Error("Expected tag 258. Got " + tag); + } else { + nonEmptyTag = true; + } } - reader.readArray( + const { items, definiteEncoding } = reader.readArray( (reader, idx) => - ret.add(Credential.deserialize(reader, [...path, "Credential#" + idx])), + Credential.deserialize(reader, [...path, "Credential#" + idx]), path, ); + let ret = new Credentials(definiteEncoding, nonEmptyTag); + ret.setItems(items); return ret; } serialize(writer: CBORWriter): void { - writer.writeTaggedTag(258); + if (this.nonEmptyTag) { + writer.writeTaggedTag(258); + } writer.writeArray(this.items, (writer, x) => x.serialize(writer)); } @@ -3585,15 +3999,18 @@ export class DRep { }; break; + + default: + throw new Error( + "Unexpected tag for DRep: " + tag + "(at " + path.join("/") + ")", + ); } if (len == null) { reader.readBreak(); } - throw new Error( - "Unexpected tag for DRep: " + tag + "(at " + path.join("/") + ")", - ); + return new DRep(variant); } serialize(writer: CBORWriter): void { @@ -4060,7 +4477,7 @@ export class DRepVotingThresholds { if (len != null && len < 10) { throw new Error( - "Insufficient number of fields in record. Expected 10. Received " + + "Insufficient number of fields in record. Expected at least 10. Received " + len + "(at " + path.join("/"), @@ -4163,7 +4580,9 @@ export class DRepVotingThresholds { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(10); + let arrayLen = 10; + + writer.writeArrayTag(arrayLen); this._motion_no_confidence.serialize(writer); this._committee_normal.serialize(writer); @@ -4210,6 +4629,73 @@ export class DRepVotingThresholds { } } +export class Data { + private inner: Uint8Array; + + constructor(inner: Uint8Array) { + this.inner = inner; + } + + static new(inner: Uint8Array): Data { + return new Data(inner); + } + + encoded_plutus_data(): Uint8Array { + return this.inner; + } + + static deserialize(reader: CBORReader, path: string[] = ["Data"]): Data { + let taggedTag = reader.readTaggedTag(path); + if (taggedTag != 24) { + throw new Error( + "Expected tag 24, got " + taggedTag + " (at " + path + ")", + ); + } + + return Data.deserializeInner(reader, path); + } + + static deserializeInner(reader: CBORReader, path: string[]): Data { + return new Data(reader.readBytes(path)); + } + + serialize(writer: CBORWriter): void { + writer.writeTaggedTag(24); + + this.serializeInner(writer); + } + + serializeInner(writer: CBORWriter): void { + writer.writeBytes(this.inner); + } + + // no-op + free(): void {} + + static from_bytes(data: Uint8Array, path: string[] = ["Data"]): Data { + let reader = new CBORReader(data); + return Data.deserialize(reader, path); + } + + static from_hex(hex_str: string, path: string[] = ["Data"]): Data { + return Data.from_bytes(hexToBytes(hex_str), path); + } + + to_bytes(): Uint8Array { + let writer = new CBORWriter(); + this.serialize(writer); + return writer.getBytes(); + } + + to_hex(): string { + return bytesToHex(this.to_bytes()); + } + + clone(path: string[]): Data { + return Data.from_bytes(this.to_bytes(), path); + } +} + export class DataCost { private _coins_per_byte: BigNum; @@ -4234,7 +4720,7 @@ export class DataCost { if (len != null && len < 1) { throw new Error( - "Insufficient number of fields in record. Expected 1. Received " + + "Insufficient number of fields in record. Expected at least 1. Received " + len + "(at " + path.join("/"), @@ -4248,7 +4734,9 @@ export class DataCost { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(1); + let arrayLen = 1; + + writer.writeArrayTag(arrayLen); this._coins_per_byte.serialize(writer); } @@ -4340,12 +4828,12 @@ export class DataHash { export enum DataOptionKind { DataHash = 0, - PlutusData = 1, + Data = 1, } export type DataOptionVariant = | { kind: 0; value: DataHash } - | { kind: 1; value: PlutusData }; + | { kind: 1; value: Data }; export class DataOption { private variant: DataOptionVariant; @@ -4358,7 +4846,7 @@ export class DataOption { return new DataOption({ kind: 0, value: hash }); } - static new_data(data: PlutusData): DataOption { + static new_data(data: Data): DataOption { return new DataOption({ kind: 1, value: data }); } @@ -4366,7 +4854,7 @@ export class DataOption { if (this.variant.kind == 0) return this.variant.value; } - as_data(): PlutusData | undefined { + as_data(): Data | undefined { if (this.variant.kind == 1) return this.variant.value; } @@ -4393,23 +4881,30 @@ export class DataOption { case 1: if (len != null && len - 1 != 1) { - throw new Error("Expected 1 items to decode PlutusData"); + throw new Error("Expected 1 items to decode Data"); } variant = { kind: 1, - value: PlutusData.deserialize(reader, [...path, "PlutusData"]), + value: Data.deserialize(reader, [...path, "Data"]), }; break; + + default: + throw new Error( + "Unexpected tag for DataOption: " + + tag + + "(at " + + path.join("/") + + ")", + ); } if (len == null) { reader.readBreak(); } - throw new Error( - "Unexpected tag for DataOption: " + tag + "(at " + path.join("/") + ")", - ); + return new DataOption(variant); } serialize(writer: CBORWriter): void { @@ -4526,15 +5021,22 @@ export class DatumSource { }; break; + + default: + throw new Error( + "Unexpected tag for DatumSource: " + + tag + + "(at " + + path.join("/") + + ")", + ); } if (len == null) { reader.readBreak(); } - throw new Error( - "Unexpected tag for DatumSource: " + tag + "(at " + path.join("/") + ")", - ); + return new DatumSource(variant); } serialize(writer: CBORWriter): void { @@ -4649,9 +5151,17 @@ export class Ed25519KeyHash { export class Ed25519KeyHashes { private items: Ed25519KeyHash[]; + private definiteEncoding: boolean; + private nonEmptyTag: boolean; + + private setItems(items: Ed25519KeyHash[]) { + this.items = items; + } - constructor() { + constructor(definiteEncoding: boolean = true, nonEmptyTag: boolean = true) { this.items = []; + this.definiteEncoding = definiteEncoding; + this.nonEmptyTag = nonEmptyTag; } static new(): Ed25519KeyHashes { @@ -4683,26 +5193,29 @@ export class Ed25519KeyHashes { } static deserialize(reader: CBORReader, path: string[]): Ed25519KeyHashes { - let ret = new Ed25519KeyHashes(); + let nonEmptyTag = false; if (reader.peekType(path) == "tagged") { let tag = reader.readTaggedTag(path); - if (tag != 258) throw new Error("Expected tag 258. Got " + tag); + if (tag != 258) { + throw new Error("Expected tag 258. Got " + tag); + } else { + nonEmptyTag = true; + } } - reader.readArray( + const { items, definiteEncoding } = reader.readArray( (reader, idx) => - ret.add( - Ed25519KeyHash.deserialize(reader, [ - ...path, - "Ed25519KeyHash#" + idx, - ]), - ), + Ed25519KeyHash.deserialize(reader, [...path, "Ed25519KeyHash#" + idx]), path, ); + let ret = new Ed25519KeyHashes(definiteEncoding, nonEmptyTag); + ret.setItems(items); return ret; } serialize(writer: CBORWriter): void { - writer.writeTaggedTag(258); + if (this.nonEmptyTag) { + writer.writeTaggedTag(258); + } writer.writeArray(this.items, (writer, x) => x.serialize(writer)); } @@ -4835,7 +5348,7 @@ export class ExUnitPrices { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -4852,7 +5365,9 @@ export class ExUnitPrices { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._mem_price.serialize(writer); this._step_price.serialize(writer); @@ -4925,7 +5440,7 @@ export class ExUnits { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -4942,7 +5457,9 @@ export class ExUnits { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._mem.serialize(writer); this._steps.serialize(writer); @@ -5203,9 +5720,11 @@ export class GenesisHash { export class GenesisHashes { private items: GenesisHash[]; + private definiteEncoding: boolean; - constructor(items: GenesisHash[]) { + constructor(items: GenesisHash[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): GenesisHashes { @@ -5226,17 +5745,20 @@ export class GenesisHashes { } static deserialize(reader: CBORReader, path: string[]): GenesisHashes { - return new GenesisHashes( - reader.readArray( - (reader, idx) => - GenesisHash.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + GenesisHash.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new GenesisHashes(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -5480,19 +6002,22 @@ export class GovernanceAction { }; break; + + default: + throw new Error( + "Unexpected tag for GovernanceAction: " + + tag + + "(at " + + path.join("/") + + ")", + ); } if (len == null) { reader.readBreak(); } - throw new Error( - "Unexpected tag for GovernanceAction: " + - tag + - "(at " + - path.join("/") + - ")", - ); + return new GovernanceAction(variant); } serialize(writer: CBORWriter): void { @@ -5602,7 +6127,7 @@ export class GovernanceActionId { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -5622,7 +6147,9 @@ export class GovernanceActionId { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._transaction_id.serialize(writer); writer.writeInt(BigInt(this._index)); @@ -5663,9 +6190,11 @@ export class GovernanceActionId { export class GovernanceActionIds { private items: GovernanceActionId[]; + private definiteEncoding: boolean; - constructor(items: GovernanceActionId[]) { + constructor(items: GovernanceActionId[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): GovernanceActionIds { @@ -5686,17 +6215,20 @@ export class GovernanceActionIds { } static deserialize(reader: CBORReader, path: string[]): GovernanceActionIds { - return new GovernanceActionIds( - reader.readArray( - (reader, idx) => - GovernanceActionId.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + GovernanceActionId.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new GovernanceActionIds(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -5975,7 +6507,7 @@ export class Header { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -5992,7 +6524,9 @@ export class Header { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._header_body.serialize(writer); this._body_signature.serialize(writer); @@ -6172,7 +6706,7 @@ export class HeaderBody { if (len != null && len < 10) { throw new Error( - "Insufficient number of fields in record. Expected 10. Received " + + "Insufficient number of fields in record. Expected at least 10. Received " + len + "(at " + path.join("/"), @@ -6240,7 +6774,9 @@ export class HeaderBody { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(10); + let arrayLen = 10; + + writer.writeArrayTag(arrayLen); writer.writeInt(BigInt(this._block_number)); this._slot.serialize(writer); @@ -6470,6 +7006,77 @@ export class Int { } } +export class InvalidTransactions { + private items: Uint32Array; + private definiteEncoding: boolean; + + constructor(items: Uint32Array, definiteEncoding: boolean = true) { + this.items = items; + this.definiteEncoding = definiteEncoding; + } + + static new(): InvalidTransactions { + return new InvalidTransactions(new Uint32Array([])); + } + + len(): number { + return this.items.length; + } + + static deserialize(reader: CBORReader, path: string[]): InvalidTransactions { + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => Number(reader.readUint([...path, "Byte#" + idx])), + path, + ); + + return new InvalidTransactions(new Uint32Array(items), definiteEncoding); + } + + serialize(writer: CBORWriter): void { + writer.writeArray( + this.items, + (writer, x) => writer.writeInt(BigInt(x)), + this.definiteEncoding, + ); + } + + // no-op + free(): void {} + + static from_bytes( + data: Uint8Array, + path: string[] = ["InvalidTransactions"], + ): InvalidTransactions { + let reader = new CBORReader(data); + return InvalidTransactions.deserialize(reader, path); + } + + static from_hex( + hex_str: string, + path: string[] = ["InvalidTransactions"], + ): InvalidTransactions { + return InvalidTransactions.from_bytes(hexToBytes(hex_str), path); + } + + to_bytes(): Uint8Array { + let writer = new CBORWriter(); + this.serialize(writer); + return writer.getBytes(); + } + + to_hex(): string { + return bytesToHex(this.to_bytes()); + } + + clone(path: string[]): InvalidTransactions { + return InvalidTransactions.from_bytes(this.to_bytes(), path); + } + + as_uint32Array(): Uint32Array { + return this.items; + } +} + export class Ipv4 { private inner: Uint8Array; @@ -6767,9 +7374,11 @@ export class Language { export class Languages { private items: Language[]; + private definiteEncoding: boolean; - constructor(items: Language[]) { + constructor(items: Language[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): Languages { @@ -6790,16 +7399,19 @@ export class Languages { } static deserialize(reader: CBORReader, path: string[]): Languages { - return new Languages( - reader.readArray( - (reader, idx) => Language.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => Language.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new Languages(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -6842,9 +7454,11 @@ export class Languages { export class MetadataList { private items: TransactionMetadatum[]; + private definiteEncoding: boolean; - constructor(items: TransactionMetadatum[]) { + constructor(items: TransactionMetadatum[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): MetadataList { @@ -6865,17 +7479,20 @@ export class MetadataList { } static deserialize(reader: CBORReader, path: string[]): MetadataList { - return new MetadataList( - reader.readArray( - (reader, idx) => - TransactionMetadatum.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + TransactionMetadatum.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new MetadataList(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -7303,9 +7920,11 @@ export class MintAssets { export class MintsAssets { private items: MintAssets[]; + private definiteEncoding: boolean; - constructor(items: MintAssets[]) { + constructor(items: MintAssets[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): MintsAssets { @@ -7326,17 +7945,19 @@ export class MintsAssets { } static deserialize(reader: CBORReader, path: string[]): MintsAssets { - return new MintsAssets( - reader.readArray( - (reader, idx) => - MintAssets.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => MintAssets.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new MintsAssets(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -7773,15 +8394,22 @@ export class NativeScript { }; break; + + default: + throw new Error( + "Unexpected tag for NativeScript: " + + tag + + "(at " + + path.join("/") + + ")", + ); } if (len == null) { reader.readBreak(); } - throw new Error( - "Unexpected tag for NativeScript: " + tag + "(at " + path.join("/") + ")", - ); + return new NativeScript(variant); } serialize(writer: CBORWriter): void { @@ -7904,7 +8532,7 @@ export class NativeScriptRefInput { if (len != null && len < 3) { throw new Error( - "Insufficient number of fields in record. Expected 3. Received " + + "Insufficient number of fields in record. Expected at least 3. Received " + len + "(at " + path.join("/"), @@ -7924,7 +8552,9 @@ export class NativeScriptRefInput { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(3); + let arrayLen = 3; + + writer.writeArrayTag(arrayLen); this._script_hash.serialize(writer); this._input.serialize(writer); @@ -8030,19 +8660,22 @@ export class NativeScriptSource { }; break; - } - - if (len == null) { - reader.readBreak(); - } - throw new Error( - "Unexpected tag for NativeScriptSource: " + - tag + - "(at " + - path.join("/") + - ")", - ); + default: + throw new Error( + "Unexpected tag for NativeScriptSource: " + + tag + + "(at " + + path.join("/") + + ")", + ); + } + + if (len == null) { + reader.readBreak(); + } + + return new NativeScriptSource(variant); } serialize(writer: CBORWriter): void { @@ -8115,13 +8748,21 @@ export class NativeScriptSource { export class NativeScripts { private items: NativeScript[]; + private definiteEncoding: boolean; + private nonEmptyTag: boolean; - constructor(items: NativeScript[]) { + private setItems(items: NativeScript[]) { this.items = items; } + constructor(definiteEncoding: boolean = true, nonEmptyTag: boolean = true) { + this.items = []; + this.definiteEncoding = definiteEncoding; + this.nonEmptyTag = nonEmptyTag; + } + static new(): NativeScripts { - return new NativeScripts([]); + return new NativeScripts(); } len(): number { @@ -8133,21 +8774,45 @@ export class NativeScripts { return this.items[index]; } - add(elem: NativeScript): void { + add(elem: NativeScript): boolean { + if (this.contains(elem)) return true; this.items.push(elem); + return false; + } + + contains(elem: NativeScript): boolean { + for (let item of this.items) { + if (arrayEq(item.to_bytes(), elem.to_bytes())) { + return true; + } + } + return false; } static deserialize(reader: CBORReader, path: string[]): NativeScripts { - return new NativeScripts( - reader.readArray( - (reader, idx) => - NativeScript.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + let nonEmptyTag = false; + if (reader.peekType(path) == "tagged") { + let tag = reader.readTaggedTag(path); + if (tag != 258) { + throw new Error("Expected tag 258. Got " + tag); + } else { + nonEmptyTag = true; + } + } + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + NativeScript.deserialize(reader, [...path, "NativeScript#" + idx]), + path, ); + let ret = new NativeScripts(definiteEncoding, nonEmptyTag); + ret.setItems(items); + return ret; } serialize(writer: CBORWriter): void { + if (this.nonEmptyTag) { + writer.writeTaggedTag(258); + } writer.writeArray(this.items, (writer, x) => x.serialize(writer)); } @@ -8453,7 +9118,7 @@ export class Nonce { if (len != null && len < 1) { throw new Error( - "Insufficient number of fields in record. Expected 1. Received " + + "Insufficient number of fields in record. Expected at least 1. Received " + len + "(at " + path.join("/"), @@ -8468,7 +9133,9 @@ export class Nonce { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(1); + let arrayLen = 1; + + writer.writeArrayTag(arrayLen); if (this._hash == null) { writer.writeNull(); @@ -8578,7 +9245,7 @@ export class OperationalCert { if (len != null && len < 4) { throw new Error( - "Insufficient number of fields in record. Expected 4. Received " + + "Insufficient number of fields in record. Expected at least 4. Received " + len + "(at " + path.join("/"), @@ -8601,7 +9268,9 @@ export class OperationalCert { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(4); + let arrayLen = 4; + + writer.writeArrayTag(arrayLen); this._hot_vkey.serialize(writer); writer.writeInt(BigInt(this._sequence_number)); @@ -8705,15 +9374,22 @@ export class OutputDatum { }; break; + + default: + throw new Error( + "Unexpected tag for OutputDatum: " + + tag + + "(at " + + path.join("/") + + ")", + ); } if (len == null) { reader.readBreak(); } - throw new Error( - "Unexpected tag for OutputDatum: " + tag + "(at " + path.join("/") + ")", - ); + return new OutputDatum(variant); } serialize(writer: CBORWriter): void { @@ -9135,13 +9811,15 @@ export class PlutusData { export class PlutusList { private items: PlutusData[]; + private definiteEncoding: boolean; - constructor() { - this.items = []; + constructor(items: PlutusData[], definiteEncoding: boolean = true) { + this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): PlutusList { - return new PlutusList(); + return new PlutusList([]); } len(): number { @@ -9153,38 +9831,24 @@ export class PlutusList { return this.items[index]; } - add(elem: PlutusData): boolean { - if (this.contains(elem)) return true; + add(elem: PlutusData): void { this.items.push(elem); - return false; - } - - contains(elem: PlutusData): boolean { - for (let item of this.items) { - if (arrayEq(item.to_bytes(), elem.to_bytes())) { - return true; - } - } - return false; } static deserialize(reader: CBORReader, path: string[]): PlutusList { - let ret = new PlutusList(); - if (reader.peekType(path) == "tagged") { - let tag = reader.readTaggedTag(path); - if (tag != 258) throw new Error("Expected tag 258. Got " + tag); - } - reader.readArray( - (reader, idx) => - ret.add(PlutusData.deserialize(reader, [...path, "PlutusData#" + idx])), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => PlutusData.deserialize(reader, [...path, "Elem#" + idx]), path, ); - return ret; + return new PlutusList(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeTaggedTag(258); - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -9218,6 +9882,14 @@ export class PlutusList { clone(path: string[]): PlutusList { return PlutusList.from_bytes(this.to_bytes(), path); } + + as_set(): PlutusSet { + let set = new PlutusSet(this.definiteEncoding); + for (let i = 0; i < this.len(); i++) { + set.add(this.items[i]); + } + return set; + } } export class PlutusMap { @@ -9323,9 +9995,11 @@ export class PlutusMap { export class PlutusMapValues { private items: PlutusData[]; + private definiteEncoding: boolean; - constructor(items: PlutusData[]) { + constructor(items: PlutusData[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): PlutusMapValues { @@ -9346,17 +10020,19 @@ export class PlutusMapValues { } static deserialize(reader: CBORReader, path: string[]): PlutusMapValues { - return new PlutusMapValues( - reader.readArray( - (reader, idx) => - PlutusData.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => PlutusData.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new PlutusMapValues(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -9458,13 +10134,21 @@ export class PlutusScript { export class PlutusScripts { private items: PlutusScript[]; + private definiteEncoding: boolean; + private nonEmptyTag: boolean; - constructor(items: PlutusScript[]) { + private setItems(items: PlutusScript[]) { this.items = items; } + constructor(definiteEncoding: boolean = true, nonEmptyTag: boolean = true) { + this.items = []; + this.definiteEncoding = definiteEncoding; + this.nonEmptyTag = nonEmptyTag; + } + static new(): PlutusScripts { - return new PlutusScripts([]); + return new PlutusScripts(); } len(): number { @@ -9476,21 +10160,45 @@ export class PlutusScripts { return this.items[index]; } - add(elem: PlutusScript): void { + add(elem: PlutusScript): boolean { + if (this.contains(elem)) return true; this.items.push(elem); + return false; + } + + contains(elem: PlutusScript): boolean { + for (let item of this.items) { + if (arrayEq(item.to_bytes(), elem.to_bytes())) { + return true; + } + } + return false; } static deserialize(reader: CBORReader, path: string[]): PlutusScripts { - return new PlutusScripts( - reader.readArray( - (reader, idx) => - PlutusScript.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + let nonEmptyTag = false; + if (reader.peekType(path) == "tagged") { + let tag = reader.readTaggedTag(path); + if (tag != 258) { + throw new Error("Expected tag 258. Got " + tag); + } else { + nonEmptyTag = true; + } + } + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + PlutusScript.deserialize(reader, [...path, "PlutusScript#" + idx]), + path, ); + let ret = new PlutusScripts(definiteEncoding, nonEmptyTag); + ret.setItems(items); + return ret; } serialize(writer: CBORWriter): void { + if (this.nonEmptyTag) { + writer.writeTaggedTag(258); + } writer.writeArray(this.items, (writer, x) => x.serialize(writer)); } @@ -9527,6 +10235,110 @@ export class PlutusScripts { } } +export class PlutusSet { + private items: PlutusData[]; + private definiteEncoding: boolean; + private nonEmptyTag: boolean; + + private setItems(items: PlutusData[]) { + this.items = items; + } + + constructor(definiteEncoding: boolean = true, nonEmptyTag: boolean = true) { + this.items = []; + this.definiteEncoding = definiteEncoding; + this.nonEmptyTag = nonEmptyTag; + } + + static new(): PlutusSet { + return new PlutusSet(); + } + + len(): number { + return this.items.length; + } + + get(index: number): PlutusData { + if (index >= this.items.length) throw new Error("Array out of bounds"); + return this.items[index]; + } + + add(elem: PlutusData): boolean { + if (this.contains(elem)) return true; + this.items.push(elem); + return false; + } + + contains(elem: PlutusData): boolean { + for (let item of this.items) { + if (arrayEq(item.to_bytes(), elem.to_bytes())) { + return true; + } + } + return false; + } + + static deserialize(reader: CBORReader, path: string[]): PlutusSet { + let nonEmptyTag = false; + if (reader.peekType(path) == "tagged") { + let tag = reader.readTaggedTag(path); + if (tag != 258) { + throw new Error("Expected tag 258. Got " + tag); + } else { + nonEmptyTag = true; + } + } + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + PlutusData.deserialize(reader, [...path, "PlutusData#" + idx]), + path, + ); + let ret = new PlutusSet(definiteEncoding, nonEmptyTag); + ret.setItems(items); + return ret; + } + + serialize(writer: CBORWriter): void { + if (this.nonEmptyTag) { + writer.writeTaggedTag(258); + } + writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + } + + // no-op + free(): void {} + + static from_bytes( + data: Uint8Array, + path: string[] = ["PlutusSet"], + ): PlutusSet { + let reader = new CBORReader(data); + return PlutusSet.deserialize(reader, path); + } + + static from_hex(hex_str: string, path: string[] = ["PlutusSet"]): PlutusSet { + return PlutusSet.from_bytes(hexToBytes(hex_str), path); + } + + to_bytes(): Uint8Array { + let writer = new CBORWriter(); + this.serialize(writer); + return writer.getBytes(); + } + + to_hex(): string { + return bytesToHex(this.to_bytes()); + } + + clone(path: string[]): PlutusSet { + return PlutusSet.from_bytes(this.to_bytes(), path); + } + + as_list(): PlutusList { + return new PlutusList(this.items, this.definiteEncoding); + } +} + export class PoolMetadata { private _url: URL; private _pool_metadata_hash: PoolMetadataHash; @@ -9561,7 +10373,7 @@ export class PoolMetadata { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -9584,7 +10396,9 @@ export class PoolMetadata { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._url.serialize(writer); this._pool_metadata_hash.serialize(writer); @@ -9873,17 +10687,343 @@ export class PoolParams { static from_bytes( data: Uint8Array, - path: string[] = ["PoolParams"], - ): PoolParams { + path: string[] = ["PoolParams"], + ): PoolParams { + let reader = new CBORReader(data); + return PoolParams.deserialize(reader, path); + } + + static from_hex( + hex_str: string, + path: string[] = ["PoolParams"], + ): PoolParams { + return PoolParams.from_bytes(hexToBytes(hex_str), path); + } + + to_bytes(): Uint8Array { + let writer = new CBORWriter(); + this.serialize(writer); + return writer.getBytes(); + } + + to_hex(): string { + return bytesToHex(this.to_bytes()); + } + + clone(path: string[]): PoolParams { + return PoolParams.from_bytes(this.to_bytes(), path); + } +} + +export class PoolRegistration { + private _pool_params: PoolParams; + + constructor(pool_params: PoolParams) { + this._pool_params = pool_params; + } + + static new(pool_params: PoolParams) { + return new PoolRegistration(pool_params); + } + + pool_params(): PoolParams { + return this._pool_params; + } + + set_pool_params(pool_params: PoolParams): void { + this._pool_params = pool_params; + } + + static deserialize(reader: CBORReader, path: string[]): PoolRegistration { + let pool_params = PoolParams.deserialize(reader, [...path, "PoolParams"]); + return new PoolRegistration(pool_params); + } + + serialize(writer: CBORWriter): void { + this._pool_params.serialize(writer); + } + + // no-op + free(): void {} + + static from_bytes( + data: Uint8Array, + path: string[] = ["PoolRegistration"], + ): PoolRegistration { + let reader = new CBORReader(data); + return PoolRegistration.deserialize(reader, path); + } + + static from_hex( + hex_str: string, + path: string[] = ["PoolRegistration"], + ): PoolRegistration { + return PoolRegistration.from_bytes(hexToBytes(hex_str), path); + } + + to_bytes(): Uint8Array { + let writer = new CBORWriter(); + this.serialize(writer); + return writer.getBytes(); + } + + to_hex(): string { + return bytesToHex(this.to_bytes()); + } + + clone(path: string[]): PoolRegistration { + return PoolRegistration.from_bytes(this.to_bytes(), path); + } +} + +export class PoolRetirement { + private _pool_keyhash: Ed25519KeyHash; + private _epoch: number; + + constructor(pool_keyhash: Ed25519KeyHash, epoch: number) { + this._pool_keyhash = pool_keyhash; + this._epoch = epoch; + } + + static new(pool_keyhash: Ed25519KeyHash, epoch: number) { + return new PoolRetirement(pool_keyhash, epoch); + } + + pool_keyhash(): Ed25519KeyHash { + return this._pool_keyhash; + } + + set_pool_keyhash(pool_keyhash: Ed25519KeyHash): void { + this._pool_keyhash = pool_keyhash; + } + + epoch(): number { + return this._epoch; + } + + set_epoch(epoch: number): void { + this._epoch = epoch; + } + + static deserialize(reader: CBORReader, path: string[]): PoolRetirement { + let pool_keyhash = Ed25519KeyHash.deserialize(reader, [ + ...path, + "pool_keyhash", + ]); + + let epoch = Number(reader.readInt([...path, "epoch"])); + + return new PoolRetirement(pool_keyhash, epoch); + } + + serialize(writer: CBORWriter): void { + this._pool_keyhash.serialize(writer); + writer.writeInt(BigInt(this._epoch)); + } + + // no-op + free(): void {} + + static from_bytes( + data: Uint8Array, + path: string[] = ["PoolRetirement"], + ): PoolRetirement { + let reader = new CBORReader(data); + return PoolRetirement.deserialize(reader, path); + } + + static from_hex( + hex_str: string, + path: string[] = ["PoolRetirement"], + ): PoolRetirement { + return PoolRetirement.from_bytes(hexToBytes(hex_str), path); + } + + to_bytes(): Uint8Array { + let writer = new CBORWriter(); + this.serialize(writer); + return writer.getBytes(); + } + + to_hex(): string { + return bytesToHex(this.to_bytes()); + } + + clone(path: string[]): PoolRetirement { + return PoolRetirement.from_bytes(this.to_bytes(), path); + } +} + +export class PoolVotingThresholds { + private _motion_no_confidence: UnitInterval; + private _committee_normal: UnitInterval; + private _committee_no_confidence: UnitInterval; + private _hard_fork_initiation: UnitInterval; + private _security_relevant_threshold: UnitInterval; + + constructor( + motion_no_confidence: UnitInterval, + committee_normal: UnitInterval, + committee_no_confidence: UnitInterval, + hard_fork_initiation: UnitInterval, + security_relevant_threshold: UnitInterval, + ) { + this._motion_no_confidence = motion_no_confidence; + this._committee_normal = committee_normal; + this._committee_no_confidence = committee_no_confidence; + this._hard_fork_initiation = hard_fork_initiation; + this._security_relevant_threshold = security_relevant_threshold; + } + + static new( + motion_no_confidence: UnitInterval, + committee_normal: UnitInterval, + committee_no_confidence: UnitInterval, + hard_fork_initiation: UnitInterval, + security_relevant_threshold: UnitInterval, + ) { + return new PoolVotingThresholds( + motion_no_confidence, + committee_normal, + committee_no_confidence, + hard_fork_initiation, + security_relevant_threshold, + ); + } + + motion_no_confidence(): UnitInterval { + return this._motion_no_confidence; + } + + set_motion_no_confidence(motion_no_confidence: UnitInterval): void { + this._motion_no_confidence = motion_no_confidence; + } + + committee_normal(): UnitInterval { + return this._committee_normal; + } + + set_committee_normal(committee_normal: UnitInterval): void { + this._committee_normal = committee_normal; + } + + committee_no_confidence(): UnitInterval { + return this._committee_no_confidence; + } + + set_committee_no_confidence(committee_no_confidence: UnitInterval): void { + this._committee_no_confidence = committee_no_confidence; + } + + hard_fork_initiation(): UnitInterval { + return this._hard_fork_initiation; + } + + set_hard_fork_initiation(hard_fork_initiation: UnitInterval): void { + this._hard_fork_initiation = hard_fork_initiation; + } + + security_relevant_threshold(): UnitInterval { + return this._security_relevant_threshold; + } + + set_security_relevant_threshold( + security_relevant_threshold: UnitInterval, + ): void { + this._security_relevant_threshold = security_relevant_threshold; + } + + static deserialize(reader: CBORReader, path: string[]): PoolVotingThresholds { + let len = reader.readArrayTag(path); + + if (len != null && len < 5) { + throw new Error( + "Insufficient number of fields in record. Expected at least 5. Received " + + len + + "(at " + + path.join("/"), + ); + } + + const motion_no_confidence_path = [ + ...path, + "UnitInterval(motion_no_confidence)", + ]; + let motion_no_confidence = UnitInterval.deserialize( + reader, + motion_no_confidence_path, + ); + + const committee_normal_path = [...path, "UnitInterval(committee_normal)"]; + let committee_normal = UnitInterval.deserialize( + reader, + committee_normal_path, + ); + + const committee_no_confidence_path = [ + ...path, + "UnitInterval(committee_no_confidence)", + ]; + let committee_no_confidence = UnitInterval.deserialize( + reader, + committee_no_confidence_path, + ); + + const hard_fork_initiation_path = [ + ...path, + "UnitInterval(hard_fork_initiation)", + ]; + let hard_fork_initiation = UnitInterval.deserialize( + reader, + hard_fork_initiation_path, + ); + + const security_relevant_threshold_path = [ + ...path, + "UnitInterval(security_relevant_threshold)", + ]; + let security_relevant_threshold = UnitInterval.deserialize( + reader, + security_relevant_threshold_path, + ); + + return new PoolVotingThresholds( + motion_no_confidence, + committee_normal, + committee_no_confidence, + hard_fork_initiation, + security_relevant_threshold, + ); + } + + serialize(writer: CBORWriter): void { + let arrayLen = 5; + + writer.writeArrayTag(arrayLen); + + this._motion_no_confidence.serialize(writer); + this._committee_normal.serialize(writer); + this._committee_no_confidence.serialize(writer); + this._hard_fork_initiation.serialize(writer); + this._security_relevant_threshold.serialize(writer); + } + + // no-op + free(): void {} + + static from_bytes( + data: Uint8Array, + path: string[] = ["PoolVotingThresholds"], + ): PoolVotingThresholds { let reader = new CBORReader(data); - return PoolParams.deserialize(reader, path); + return PoolVotingThresholds.deserialize(reader, path); } static from_hex( hex_str: string, - path: string[] = ["PoolParams"], - ): PoolParams { - return PoolParams.from_bytes(hexToBytes(hex_str), path); + path: string[] = ["PoolVotingThresholds"], + ): PoolVotingThresholds { + return PoolVotingThresholds.from_bytes(hexToBytes(hex_str), path); } to_bytes(): Uint8Array { @@ -9896,115 +11036,152 @@ export class PoolParams { return bytesToHex(this.to_bytes()); } - clone(path: string[]): PoolParams { - return PoolParams.from_bytes(this.to_bytes(), path); + clone(path: string[]): PoolVotingThresholds { + return PoolVotingThresholds.from_bytes(this.to_bytes(), path); } } -export class PoolRegistration { - private _pool_params: PoolParams; +export class PostAlonzoTransactionOutput { + private _address: Address; + private _amount: Value; + private _datum_option: DataOption | undefined; + private _script_ref: ScriptRef | undefined; - constructor(pool_params: PoolParams) { - this._pool_params = pool_params; + constructor( + address: Address, + amount: Value, + datum_option: DataOption | undefined, + script_ref: ScriptRef | undefined, + ) { + this._address = address; + this._amount = amount; + this._datum_option = datum_option; + this._script_ref = script_ref; } - static new(pool_params: PoolParams) { - return new PoolRegistration(pool_params); + static new( + address: Address, + amount: Value, + datum_option: DataOption | undefined, + script_ref: ScriptRef | undefined, + ) { + return new PostAlonzoTransactionOutput( + address, + amount, + datum_option, + script_ref, + ); } - pool_params(): PoolParams { - return this._pool_params; + address(): Address { + return this._address; } - set_pool_params(pool_params: PoolParams): void { - this._pool_params = pool_params; + set_address(address: Address): void { + this._address = address; } - static deserialize(reader: CBORReader, path: string[]): PoolRegistration { - let pool_params = PoolParams.deserialize(reader, [...path, "PoolParams"]); - return new PoolRegistration(pool_params); + amount(): Value { + return this._amount; } - serialize(writer: CBORWriter): void { - this._pool_params.serialize(writer); + set_amount(amount: Value): void { + this._amount = amount; } - // no-op - free(): void {} - - static from_bytes( - data: Uint8Array, - path: string[] = ["PoolRegistration"], - ): PoolRegistration { - let reader = new CBORReader(data); - return PoolRegistration.deserialize(reader, path); + datum_option(): DataOption | undefined { + return this._datum_option; } - static from_hex( - hex_str: string, - path: string[] = ["PoolRegistration"], - ): PoolRegistration { - return PoolRegistration.from_bytes(hexToBytes(hex_str), path); + set_datum_option(datum_option: DataOption | undefined): void { + this._datum_option = datum_option; } - to_bytes(): Uint8Array { - let writer = new CBORWriter(); - this.serialize(writer); - return writer.getBytes(); + script_ref(): ScriptRef | undefined { + return this._script_ref; } - to_hex(): string { - return bytesToHex(this.to_bytes()); + set_script_ref(script_ref: ScriptRef | undefined): void { + this._script_ref = script_ref; } - clone(path: string[]): PoolRegistration { - return PoolRegistration.from_bytes(this.to_bytes(), path); - } -} + static deserialize( + reader: CBORReader, + path: string[], + ): PostAlonzoTransactionOutput { + let fields: any = {}; + reader.readMap((r) => { + let key = Number(r.readUint(path)); + switch (key) { + case 0: { + const new_path = [...path, "Address(address)"]; + fields.address = Address.deserialize(r, new_path); + break; + } -export class PoolRetirement { - private _pool_keyhash: Ed25519KeyHash; - private _epoch: number; + case 1: { + const new_path = [...path, "Value(amount)"]; + fields.amount = Value.deserialize(r, new_path); + break; + } - constructor(pool_keyhash: Ed25519KeyHash, epoch: number) { - this._pool_keyhash = pool_keyhash; - this._epoch = epoch; - } + case 2: { + const new_path = [...path, "DataOption(datum_option)"]; + fields.datum_option = DataOption.deserialize(r, new_path); + break; + } - static new(pool_keyhash: Ed25519KeyHash, epoch: number) { - return new PoolRetirement(pool_keyhash, epoch); - } + case 3: { + const new_path = [...path, "ScriptRef(script_ref)"]; + fields.script_ref = ScriptRef.deserialize(r, new_path); + break; + } + } + }, path); - pool_keyhash(): Ed25519KeyHash { - return this._pool_keyhash; - } + if (fields.address === undefined) + throw new Error( + "Value not provided for field 0 (address) (at " + path.join("/") + ")", + ); + let address = fields.address; + if (fields.amount === undefined) + throw new Error( + "Value not provided for field 1 (amount) (at " + path.join("/") + ")", + ); + let amount = fields.amount; - set_pool_keyhash(pool_keyhash: Ed25519KeyHash): void { - this._pool_keyhash = pool_keyhash; - } + let datum_option = fields.datum_option; - epoch(): number { - return this._epoch; - } + let script_ref = fields.script_ref; - set_epoch(epoch: number): void { - this._epoch = epoch; + return new PostAlonzoTransactionOutput( + address, + amount, + datum_option, + script_ref, + ); } - static deserialize(reader: CBORReader, path: string[]): PoolRetirement { - let pool_keyhash = Ed25519KeyHash.deserialize(reader, [ - ...path, - "pool_keyhash", - ]); + serialize(writer: CBORWriter): void { + let len = 4; + if (this._datum_option === undefined) len -= 1; + if (this._script_ref === undefined) len -= 1; + writer.writeMapTag(len); - let epoch = Number(reader.readInt([...path, "epoch"])); + writer.writeInt(0n); + this._address.serialize(writer); - return new PoolRetirement(pool_keyhash, epoch); - } + writer.writeInt(1n); + this._amount.serialize(writer); - serialize(writer: CBORWriter): void { - this._pool_keyhash.serialize(writer); - writer.writeInt(BigInt(this._epoch)); + if (this._datum_option !== undefined) { + writer.writeInt(2n); + this._datum_option.serialize(writer); + } + if (this._script_ref !== undefined) { + writer.writeInt(3n); + this._script_ref.serialize(writer); + } } // no-op @@ -10012,17 +11189,17 @@ export class PoolRetirement { static from_bytes( data: Uint8Array, - path: string[] = ["PoolRetirement"], - ): PoolRetirement { + path: string[] = ["PostAlonzoTransactionOutput"], + ): PostAlonzoTransactionOutput { let reader = new CBORReader(data); - return PoolRetirement.deserialize(reader, path); + return PostAlonzoTransactionOutput.deserialize(reader, path); } static from_hex( hex_str: string, - path: string[] = ["PoolRetirement"], - ): PoolRetirement { - return PoolRetirement.from_bytes(hexToBytes(hex_str), path); + path: string[] = ["PostAlonzoTransactionOutput"], + ): PostAlonzoTransactionOutput { + return PostAlonzoTransactionOutput.from_bytes(hexToBytes(hex_str), path); } to_bytes(): Uint8Array { @@ -10035,161 +11212,102 @@ export class PoolRetirement { return bytesToHex(this.to_bytes()); } - clone(path: string[]): PoolRetirement { - return PoolRetirement.from_bytes(this.to_bytes(), path); + clone(path: string[]): PostAlonzoTransactionOutput { + return PostAlonzoTransactionOutput.from_bytes(this.to_bytes(), path); } } -export class PoolVotingThresholds { - private _motion_no_confidence: UnitInterval; - private _committee_normal: UnitInterval; - private _committee_no_confidence: UnitInterval; - private _hard_fork_initiation: UnitInterval; - private _security_relevant_threshold: UnitInterval; +export class PreBabbageTransactionOutput { + private _address: Address; + private _amount: Value; + private _datum_hash: DataHash | undefined; constructor( - motion_no_confidence: UnitInterval, - committee_normal: UnitInterval, - committee_no_confidence: UnitInterval, - hard_fork_initiation: UnitInterval, - security_relevant_threshold: UnitInterval, + address: Address, + amount: Value, + datum_hash: DataHash | undefined, ) { - this._motion_no_confidence = motion_no_confidence; - this._committee_normal = committee_normal; - this._committee_no_confidence = committee_no_confidence; - this._hard_fork_initiation = hard_fork_initiation; - this._security_relevant_threshold = security_relevant_threshold; + this._address = address; + this._amount = amount; + this._datum_hash = datum_hash; } static new( - motion_no_confidence: UnitInterval, - committee_normal: UnitInterval, - committee_no_confidence: UnitInterval, - hard_fork_initiation: UnitInterval, - security_relevant_threshold: UnitInterval, + address: Address, + amount: Value, + datum_hash: DataHash | undefined, ) { - return new PoolVotingThresholds( - motion_no_confidence, - committee_normal, - committee_no_confidence, - hard_fork_initiation, - security_relevant_threshold, - ); - } - - motion_no_confidence(): UnitInterval { - return this._motion_no_confidence; - } - - set_motion_no_confidence(motion_no_confidence: UnitInterval): void { - this._motion_no_confidence = motion_no_confidence; + return new PreBabbageTransactionOutput(address, amount, datum_hash); } - committee_normal(): UnitInterval { - return this._committee_normal; - } - - set_committee_normal(committee_normal: UnitInterval): void { - this._committee_normal = committee_normal; - } - - committee_no_confidence(): UnitInterval { - return this._committee_no_confidence; + address(): Address { + return this._address; } - set_committee_no_confidence(committee_no_confidence: UnitInterval): void { - this._committee_no_confidence = committee_no_confidence; + set_address(address: Address): void { + this._address = address; } - hard_fork_initiation(): UnitInterval { - return this._hard_fork_initiation; + amount(): Value { + return this._amount; } - set_hard_fork_initiation(hard_fork_initiation: UnitInterval): void { - this._hard_fork_initiation = hard_fork_initiation; + set_amount(amount: Value): void { + this._amount = amount; } - security_relevant_threshold(): UnitInterval { - return this._security_relevant_threshold; + datum_hash(): DataHash | undefined { + return this._datum_hash; } - set_security_relevant_threshold( - security_relevant_threshold: UnitInterval, - ): void { - this._security_relevant_threshold = security_relevant_threshold; + set_datum_hash(datum_hash: DataHash | undefined): void { + this._datum_hash = datum_hash; } - static deserialize(reader: CBORReader, path: string[]): PoolVotingThresholds { + static deserialize( + reader: CBORReader, + path: string[], + ): PreBabbageTransactionOutput { let len = reader.readArrayTag(path); - if (len != null && len < 5) { + if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 5. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), ); } - const motion_no_confidence_path = [ - ...path, - "UnitInterval(motion_no_confidence)", - ]; - let motion_no_confidence = UnitInterval.deserialize( - reader, - motion_no_confidence_path, - ); - - const committee_normal_path = [...path, "UnitInterval(committee_normal)"]; - let committee_normal = UnitInterval.deserialize( - reader, - committee_normal_path, - ); - - const committee_no_confidence_path = [ - ...path, - "UnitInterval(committee_no_confidence)", - ]; - let committee_no_confidence = UnitInterval.deserialize( - reader, - committee_no_confidence_path, - ); + const address_path = [...path, "Address(address)"]; + let address = Address.deserialize(reader, address_path); - const hard_fork_initiation_path = [ - ...path, - "UnitInterval(hard_fork_initiation)", - ]; - let hard_fork_initiation = UnitInterval.deserialize( - reader, - hard_fork_initiation_path, - ); + const amount_path = [...path, "Value(amount)"]; + let amount = Value.deserialize(reader, amount_path); - const security_relevant_threshold_path = [ - ...path, - "UnitInterval(security_relevant_threshold)", - ]; - let security_relevant_threshold = UnitInterval.deserialize( - reader, - security_relevant_threshold_path, - ); + const datum_hash_path = [...path, "DataHash(datum_hash)"]; + let datum_hash = + len != null && len > 2 + ? DataHash.deserialize(reader, datum_hash_path) + : undefined; - return new PoolVotingThresholds( - motion_no_confidence, - committee_normal, - committee_no_confidence, - hard_fork_initiation, - security_relevant_threshold, - ); + return new PreBabbageTransactionOutput(address, amount, datum_hash); } serialize(writer: CBORWriter): void { - writer.writeArrayTag(5); + let arrayLen = 2; - this._motion_no_confidence.serialize(writer); - this._committee_normal.serialize(writer); - this._committee_no_confidence.serialize(writer); - this._hard_fork_initiation.serialize(writer); - this._security_relevant_threshold.serialize(writer); + if (this._datum_hash) { + arrayLen++; + } + + writer.writeArrayTag(arrayLen); + + this._address.serialize(writer); + this._amount.serialize(writer); + if (this._datum_hash) { + this._datum_hash.serialize(writer); + } } // no-op @@ -10197,17 +11315,17 @@ export class PoolVotingThresholds { static from_bytes( data: Uint8Array, - path: string[] = ["PoolVotingThresholds"], - ): PoolVotingThresholds { + path: string[] = ["PreBabbageTransactionOutput"], + ): PreBabbageTransactionOutput { let reader = new CBORReader(data); - return PoolVotingThresholds.deserialize(reader, path); + return PreBabbageTransactionOutput.deserialize(reader, path); } static from_hex( hex_str: string, - path: string[] = ["PoolVotingThresholds"], - ): PoolVotingThresholds { - return PoolVotingThresholds.from_bytes(hexToBytes(hex_str), path); + path: string[] = ["PreBabbageTransactionOutput"], + ): PreBabbageTransactionOutput { + return PreBabbageTransactionOutput.from_bytes(hexToBytes(hex_str), path); } to_bytes(): Uint8Array { @@ -10220,8 +11338,8 @@ export class PoolVotingThresholds { return bytesToHex(this.to_bytes()); } - clone(path: string[]): PoolVotingThresholds { - return PoolVotingThresholds.from_bytes(this.to_bytes(), path); + clone(path: string[]): PreBabbageTransactionOutput { + return PreBabbageTransactionOutput.from_bytes(this.to_bytes(), path); } } @@ -11362,7 +12480,7 @@ export class ProtocolVersion { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -11379,7 +12497,9 @@ export class ProtocolVersion { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); writer.writeInt(BigInt(this._major)); writer.writeInt(BigInt(this._minor)); @@ -11490,98 +12610,22 @@ export class PublicKey { } export class Redeemer { - private _tag: RedeemerTag; - private _index: BigNum; - private _data: PlutusData; - private _ex_units: ExUnits; - - constructor( - tag: RedeemerTag, - index: BigNum, - data: PlutusData, - ex_units: ExUnits, - ) { - this._tag = tag; - this._index = index; - this._data = data; - this._ex_units = ex_units; - } - - static new( - tag: RedeemerTag, - index: BigNum, - data: PlutusData, - ex_units: ExUnits, - ) { - return new Redeemer(tag, index, data, ex_units); - } + private inner: RedeemersArrayItem; - tag(): RedeemerTag { - return this._tag; - } - - set_tag(tag: RedeemerTag): void { - this._tag = tag; - } - - index(): BigNum { - return this._index; - } - - set_index(index: BigNum): void { - this._index = index; - } - - data(): PlutusData { - return this._data; - } - - set_data(data: PlutusData): void { - this._data = data; - } - - ex_units(): ExUnits { - return this._ex_units; + constructor(inner: RedeemersArrayItem) { + this.inner = inner; } - set_ex_units(ex_units: ExUnits): void { - this._ex_units = ex_units; + redeemerArrayItem(): RedeemersArrayItem { + return this.inner; } static deserialize(reader: CBORReader, path: string[]): Redeemer { - let len = reader.readArrayTag(path); - - if (len != null && len < 4) { - throw new Error( - "Insufficient number of fields in record. Expected 4. Received " + - len + - "(at " + - path.join("/"), - ); - } - - const tag_path = [...path, "RedeemerTag(tag)"]; - let tag = RedeemerTag.deserialize(reader, tag_path); - - const index_path = [...path, "BigNum(index)"]; - let index = BigNum.deserialize(reader, index_path); - - const data_path = [...path, "PlutusData(data)"]; - let data = PlutusData.deserialize(reader, data_path); - - const ex_units_path = [...path, "ExUnits(ex_units)"]; - let ex_units = ExUnits.deserialize(reader, ex_units_path); - - return new Redeemer(tag, index, data, ex_units); + return new Redeemer(RedeemersArrayItem.deserialize(reader, path)); } serialize(writer: CBORWriter): void { - writer.writeArrayTag(4); - - this._tag.serialize(writer); - this._index.serialize(writer); - this._data.serialize(writer); - this._ex_units.serialize(writer); + this.inner.serialize(writer); } // no-op @@ -11609,6 +12653,15 @@ export class Redeemer { clone(path: string[]): Redeemer { return Redeemer.from_bytes(this.to_bytes(), path); } + + static new( + tag: RedeemerTag, + index: BigNum, + data: PlutusData, + ex_units: ExUnits, + ) { + return new Redeemer(new RedeemersArrayItem(tag, index, data, ex_units)); + } } export enum RedeemerTagKind { @@ -11682,17 +12735,135 @@ export class RedeemerTag { static from_bytes( data: Uint8Array, - path: string[] = ["RedeemerTag"], - ): RedeemerTag { + path: string[] = ["RedeemerTag"], + ): RedeemerTag { + let reader = new CBORReader(data); + return RedeemerTag.deserialize(reader, path); + } + + static from_hex( + hex_str: string, + path: string[] = ["RedeemerTag"], + ): RedeemerTag { + return RedeemerTag.from_bytes(hexToBytes(hex_str), path); + } + + to_bytes(): Uint8Array { + let writer = new CBORWriter(); + this.serialize(writer); + return writer.getBytes(); + } + + to_hex(): string { + return bytesToHex(this.to_bytes()); + } + + clone(path: string[]): RedeemerTag { + return RedeemerTag.from_bytes(this.to_bytes(), path); + } +} + +export enum RedeemersKind { + RedeemersArray = 0, + RedeemersMap = 1, +} + +export type RedeemersVariant = + | { kind: 0; value: RedeemersArray } + | { kind: 1; value: RedeemersMap }; + +export class Redeemers { + private variant: RedeemersVariant; + + constructor(variant: RedeemersVariant) { + this.variant = variant; + } + + static new_redeemers_array(redeemers_array: RedeemersArray): Redeemers { + return new Redeemers({ kind: 0, value: redeemers_array }); + } + + static new_redeemers_map(redeemers_map: RedeemersMap): Redeemers { + return new Redeemers({ kind: 1, value: redeemers_map }); + } + + as_redeemers_array(): RedeemersArray { + if (this.variant.kind == 0) return this.variant.value; + throw new Error("Incorrect cast"); + } + + as_redeemers_map(): RedeemersMap { + if (this.variant.kind == 1) return this.variant.value; + throw new Error("Incorrect cast"); + } + + kind(): RedeemersKind { + return this.variant.kind; + } + + static deserialize(reader: CBORReader, path: string[]): Redeemers { + let tag = reader.peekType(path); + let variant: RedeemersVariant; + + switch (tag) { + case "array": + variant = { + kind: RedeemersKind.RedeemersArray, + value: RedeemersArray.deserialize(reader, [ + ...path, + "RedeemersArray(redeemers_array)", + ]), + }; + break; + + case "map": + variant = { + kind: RedeemersKind.RedeemersMap, + value: RedeemersMap.deserialize(reader, [ + ...path, + "RedeemersMap(redeemers_map)", + ]), + }; + break; + + default: + throw new Error( + "Unexpected subtype for Redeemers: " + + tag + + "(at " + + path.join("/") + + ")", + ); + } + + return new Redeemers(variant); + } + + serialize(writer: CBORWriter): void { + switch (this.variant.kind) { + case 0: + this.variant.value.serialize(writer); + break; + + case 1: + this.variant.value.serialize(writer); + break; + } + } + + // no-op + free(): void {} + + static from_bytes( + data: Uint8Array, + path: string[] = ["Redeemers"], + ): Redeemers { let reader = new CBORReader(data); - return RedeemerTag.deserialize(reader, path); + return Redeemers.deserialize(reader, path); } - static from_hex( - hex_str: string, - path: string[] = ["RedeemerTag"], - ): RedeemerTag { - return RedeemerTag.from_bytes(hexToBytes(hex_str), path); + static from_hex(hex_str: string, path: string[] = ["Redeemers"]): Redeemers { + return Redeemers.from_bytes(hexToBytes(hex_str), path); } to_bytes(): Uint8Array { @@ -11705,48 +12876,142 @@ export class RedeemerTag { return bytesToHex(this.to_bytes()); } - clone(path: string[]): RedeemerTag { - return RedeemerTag.from_bytes(this.to_bytes(), path); + clone(path: string[]): Redeemers { + return Redeemers.from_bytes(this.to_bytes(), path); + } + + total_ex_units(): ExUnits { + let mems = BigNum.zero(), + steps = BigNum.zero(); + switch (this.variant.kind) { + case 0: { + for (let i = 0; i < this.variant.value.len(); i++) { + const item = this.variant.value.get(i); + mems = mems.checked_add(item.ex_units().mem()); + steps = steps.checked_add(item.ex_units().steps()); + } + break; + } + case 1: { + const keys = this.variant.value.keys(); + for (let i = 0; i < keys.len(); i++) { + const item = this.variant.value.get(keys.get(i)) as RedeemersValue; + mems = mems.checked_add(item.ex_units().mem()); + steps = steps.checked_add(item.ex_units().steps()); + } + break; + } + } + return ExUnits.new(mems, steps); + } + + static new(): Redeemers { + return Redeemers.new_redeemers_map(RedeemersMap.new()); + } + + len(): number { + return this.variant.value.len(); + } + + add(elem: Redeemer): void { + switch (this.variant.kind) { + case 0: + this.variant.value.add(elem.redeemerArrayItem()); + break; + case 1: { + const r = elem.redeemerArrayItem(); + this.variant.value.insert( + RedeemersKey.new(r.tag(), r.index()), + RedeemersValue.new(r.data(), r.ex_units()), + ); + break; + } + } + } + + get(index: number): Redeemer { + switch (this.variant.kind) { + case 0: + return new Redeemer(this.variant.value.get(index)); + case 1: { + const key = this.variant.value.keys().get(index); + const r = this.variant.value.get(key); + if (r === undefined) { + throw "Unexpected undefined key in Redeemers"; + } else { + return new Redeemer( + RedeemersArrayItem.new( + key.tag(), + key.index(), + r.data(), + r.ex_units(), + ), + ); + } + } + } } } -export class Redeemers { - private items: Redeemer[]; +export class RedeemersArray { + private items: RedeemersArrayItem[]; + private definiteEncoding: boolean; - constructor(items: Redeemer[]) { + constructor(items: RedeemersArrayItem[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } - static new(): Redeemers { - return new Redeemers([]); + static new(): RedeemersArray { + return new RedeemersArray([]); } len(): number { return this.items.length; } - get(index: number): Redeemer { + get(index: number): RedeemersArrayItem { if (index >= this.items.length) throw new Error("Array out of bounds"); return this.items[index]; } - add(elem: Redeemer): void { + add(elem: RedeemersArrayItem): void { this.items.push(elem); } + static deserialize(reader: CBORReader, path: string[]): RedeemersArray { + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + RedeemersArrayItem.deserialize(reader, [...path, "Elem#" + idx]), + path, + ); + return new RedeemersArray(items, definiteEncoding); + } + + serialize(writer: CBORWriter): void { + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); + } + // no-op free(): void {} static from_bytes( data: Uint8Array, - path: string[] = ["Redeemers"], - ): Redeemers { + path: string[] = ["RedeemersArray"], + ): RedeemersArray { let reader = new CBORReader(data); - return Redeemers.deserialize(reader, path); + return RedeemersArray.deserialize(reader, path); } - static from_hex(hex_str: string, path: string[] = ["Redeemers"]): Redeemers { - return Redeemers.from_bytes(hexToBytes(hex_str), path); + static from_hex( + hex_str: string, + path: string[] = ["RedeemersArray"], + ): RedeemersArray { + return RedeemersArray.from_bytes(hexToBytes(hex_str), path); } to_bytes(): Uint8Array { @@ -11759,70 +13024,8 @@ export class Redeemers { return bytesToHex(this.to_bytes()); } - clone(path: string[]): Redeemers { - return Redeemers.from_bytes(this.to_bytes(), path); - } - - total_ex_units(): ExUnits { - let mems = BigNum.zero(), - steps = BigNum.zero(); - for (let item of this.items) { - mems = mems.checked_add(item.ex_units().mem()); - steps = steps.checked_add(item.ex_units().steps()); - } - return ExUnits.new(mems, steps); - } - - static deserialize(reader: CBORReader, path: string[]): Redeemers { - if (reader.peekType(path) == "array") { - return Redeemers.deserializeArray(reader, path); - } else if (reader.peekType(path) == "map") { - return Redeemers.deserializeMap(reader, path); - } - throw new Error( - "Expected either an array or a map (at " + path.join("/") + ")", - ); - } - - static deserializeArray(reader: CBORReader, path: string[]): Redeemers { - let redeemers = Redeemers.new(); - reader.readArray((reader, idx) => { - let item = RedeemersArrayItem.deserialize(reader, [ - ...path, - "RedeemersArrayItem#" + idx, - ]); - redeemers.add( - Redeemer.new(item.tag(), item.index(), item.data(), item.ex_units()), - ); - }, path); - return redeemers; - } - - static deserializeMap(reader: CBORReader, path: string[]): Redeemers { - let redeemers = Redeemers.new(); - reader.readMap((reader, idx) => { - let key = RedeemersKey.deserialize(reader, [ - ...path, - `RedeemersKey#${idx}`, - ]); - let value = RedeemersValue.deserialize(reader, [ - ...path, - `RedeemersValue#${idx}`, - ]); - redeemers.add( - Redeemer.new(key.tag(), key.index(), value.data(), value.ex_units()), - ); - }, path); - return redeemers; - } - - serialize(writer: CBORWriter): void { - writer.writeMap(this.items, (writer, redeemer) => { - let key = RedeemersKey.new(redeemer.tag(), redeemer.index()); - let value = RedeemersValue.new(redeemer.data(), redeemer.ex_units()); - key.serialize(writer); - value.serialize(writer); - }); + clone(path: string[]): RedeemersArray { + return RedeemersArray.from_bytes(this.to_bytes(), path); } } @@ -11890,7 +13093,7 @@ export class RedeemersArrayItem { if (len != null && len < 4) { throw new Error( - "Insufficient number of fields in record. Expected 4. Received " + + "Insufficient number of fields in record. Expected at least 4. Received " + len + "(at " + path.join("/"), @@ -11913,7 +13116,9 @@ export class RedeemersArrayItem { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(4); + let arrayLen = 4; + + writer.writeArrayTag(arrayLen); this._tag.serialize(writer); this._index.serialize(writer); @@ -11988,7 +13193,7 @@ export class RedeemersKey { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -12005,7 +13210,9 @@ export class RedeemersKey { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._tag.serialize(writer); this._index.serialize(writer); @@ -12044,6 +13251,186 @@ export class RedeemersKey { } } +export class RedeemersKeys { + private items: RedeemersKey[]; + private definiteEncoding: boolean; + + constructor(items: RedeemersKey[], definiteEncoding: boolean = true) { + this.items = items; + this.definiteEncoding = definiteEncoding; + } + + static new(): RedeemersKeys { + return new RedeemersKeys([]); + } + + len(): number { + return this.items.length; + } + + get(index: number): RedeemersKey { + if (index >= this.items.length) throw new Error("Array out of bounds"); + return this.items[index]; + } + + add(elem: RedeemersKey): void { + this.items.push(elem); + } + + static deserialize(reader: CBORReader, path: string[]): RedeemersKeys { + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + RedeemersKey.deserialize(reader, [...path, "Elem#" + idx]), + path, + ); + return new RedeemersKeys(items, definiteEncoding); + } + + serialize(writer: CBORWriter): void { + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); + } + + // no-op + free(): void {} + + static from_bytes( + data: Uint8Array, + path: string[] = ["RedeemersKeys"], + ): RedeemersKeys { + let reader = new CBORReader(data); + return RedeemersKeys.deserialize(reader, path); + } + + static from_hex( + hex_str: string, + path: string[] = ["RedeemersKeys"], + ): RedeemersKeys { + return RedeemersKeys.from_bytes(hexToBytes(hex_str), path); + } + + to_bytes(): Uint8Array { + let writer = new CBORWriter(); + this.serialize(writer); + return writer.getBytes(); + } + + to_hex(): string { + return bytesToHex(this.to_bytes()); + } + + clone(path: string[]): RedeemersKeys { + return RedeemersKeys.from_bytes(this.to_bytes(), path); + } +} + +export class RedeemersMap { + _items: [RedeemersKey, RedeemersValue][]; + + constructor(items: [RedeemersKey, RedeemersValue][]) { + this._items = items; + } + + static new(): RedeemersMap { + return new RedeemersMap([]); + } + + len(): number { + return this._items.length; + } + + insert(key: RedeemersKey, value: RedeemersValue): RedeemersValue | undefined { + let entry = this._items.find((x) => + arrayEq(key.to_bytes(), x[0].to_bytes()), + ); + if (entry != null) { + let ret = entry[1]; + entry[1] = value; + return ret; + } + this._items.push([key, value]); + return undefined; + } + + get(key: RedeemersKey): RedeemersValue | undefined { + let entry = this._items.find((x) => + arrayEq(key.to_bytes(), x[0].to_bytes()), + ); + if (entry == null) return undefined; + return entry[1]; + } + + _remove_many(keys: RedeemersKey[]): void { + this._items = this._items.filter(([k, _v]) => + keys.every((key) => !arrayEq(key.to_bytes(), k.to_bytes())), + ); + } + + keys(): RedeemersKeys { + let keys = RedeemersKeys.new(); + for (let [key, _] of this._items) keys.add(key); + return keys; + } + + static deserialize(reader: CBORReader, path: string[]): RedeemersMap { + let ret = new RedeemersMap([]); + reader.readMap( + (reader, idx) => + ret.insert( + RedeemersKey.deserialize(reader, [...path, "RedeemersKey#" + idx]), + RedeemersValue.deserialize(reader, [ + ...path, + "RedeemersValue#" + idx, + ]), + ), + path, + ); + return ret; + } + + serialize(writer: CBORWriter): void { + writer.writeMap(this._items, (writer, x) => { + x[0].serialize(writer); + x[1].serialize(writer); + }); + } + + // no-op + free(): void {} + + static from_bytes( + data: Uint8Array, + path: string[] = ["RedeemersMap"], + ): RedeemersMap { + let reader = new CBORReader(data); + return RedeemersMap.deserialize(reader, path); + } + + static from_hex( + hex_str: string, + path: string[] = ["RedeemersMap"], + ): RedeemersMap { + return RedeemersMap.from_bytes(hexToBytes(hex_str), path); + } + + to_bytes(): Uint8Array { + let writer = new CBORWriter(); + this.serialize(writer); + return writer.getBytes(); + } + + to_hex(): string { + return bytesToHex(this.to_bytes()); + } + + clone(path: string[]): RedeemersMap { + return RedeemersMap.from_bytes(this.to_bytes(), path); + } +} + export class RedeemersValue { private _data: PlutusData; private _ex_units: ExUnits; @@ -12078,7 +13465,7 @@ export class RedeemersValue { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -12095,7 +13482,9 @@ export class RedeemersValue { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._data.serialize(writer); this._ex_units.serialize(writer); @@ -12296,15 +13685,18 @@ export class Relay { }; break; + + default: + throw new Error( + "Unexpected tag for Relay: " + tag + "(at " + path.join("/") + ")", + ); } if (len == null) { reader.readBreak(); } - throw new Error( - "Unexpected tag for Relay: " + tag + "(at " + path.join("/") + ")", - ); + return new Relay(variant); } serialize(writer: CBORWriter): void { @@ -12356,9 +13748,11 @@ export class Relay { export class Relays { private items: Relay[]; + private definiteEncoding: boolean; - constructor(items: Relay[]) { + constructor(items: Relay[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): Relays { @@ -12379,16 +13773,19 @@ export class Relays { } static deserialize(reader: CBORReader, path: string[]): Relays { - return new Relays( - reader.readArray( - (reader, idx) => Relay.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => Relay.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new Relays(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -12420,9 +13817,11 @@ export class Relays { export class RewardAddresses { private items: RewardAddress[]; + private definiteEncoding: boolean; - constructor(items: RewardAddress[]) { + constructor(items: RewardAddress[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): RewardAddresses { @@ -12443,17 +13842,20 @@ export class RewardAddresses { } static deserialize(reader: CBORReader, path: string[]): RewardAddresses { - return new RewardAddresses( - reader.readArray( - (reader, idx) => - RewardAddress.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + RewardAddress.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new RewardAddresses(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -12731,9 +14133,11 @@ export class ScriptHash { export class ScriptHashes { private items: ScriptHash[]; + private definiteEncoding: boolean; - constructor(items: ScriptHash[]) { + constructor(items: ScriptHash[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): ScriptHashes { @@ -12754,17 +14158,19 @@ export class ScriptHashes { } static deserialize(reader: CBORReader, path: string[]): ScriptHashes { - return new ScriptHashes( - reader.readArray( - (reader, idx) => - ScriptHash.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => ScriptHash.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new ScriptHashes(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -13104,15 +14510,22 @@ export class ScriptRef { }; break; + + default: + throw new Error( + "Unexpected tag for ScriptRef: " + + tag + + "(at " + + path.join("/") + + ")", + ); } if (len == null) { reader.readBreak(); } - throw new Error( - "Unexpected tag for ScriptRef: " + tag + "(at " + path.join("/") + ")", - ); + return new ScriptRef(variant); } serialize(writer: CBORWriter): void { @@ -14126,7 +15539,7 @@ export class Transaction { if (len != null && len < 4) { throw new Error( - "Insufficient number of fields in record. Expected 4. Received " + + "Insufficient number of fields in record. Expected at least 4. Received " + len + "(at " + path.join("/"), @@ -14156,7 +15569,9 @@ export class Transaction { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(4); + let arrayLen = 4; + + writer.writeArrayTag(arrayLen); this._body.serialize(writer); this._witness_set.serialize(writer); @@ -14211,9 +15626,11 @@ export class Transaction { export class TransactionBodies { private items: TransactionBody[]; + private definiteEncoding: boolean; - constructor(items: TransactionBody[]) { + constructor(items: TransactionBody[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): TransactionBodies { @@ -14234,17 +15651,20 @@ export class TransactionBodies { } static deserialize(reader: CBORReader, path: string[]): TransactionBodies { - return new TransactionBodies( - reader.readArray( - (reader, idx) => - TransactionBody.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + TransactionBody.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new TransactionBodies(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -14999,7 +16419,7 @@ export class TransactionInput { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -15019,7 +16439,9 @@ export class TransactionInput { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._transaction_id.serialize(writer); writer.writeInt(BigInt(this._index)); @@ -15060,9 +16482,17 @@ export class TransactionInput { export class TransactionInputs { private items: TransactionInput[]; + private definiteEncoding: boolean; + private nonEmptyTag: boolean; + + private setItems(items: TransactionInput[]) { + this.items = items; + } - constructor() { + constructor(definiteEncoding: boolean = true, nonEmptyTag: boolean = true) { this.items = []; + this.definiteEncoding = definiteEncoding; + this.nonEmptyTag = nonEmptyTag; } static new(): TransactionInputs { @@ -15094,26 +16524,32 @@ export class TransactionInputs { } static deserialize(reader: CBORReader, path: string[]): TransactionInputs { - let ret = new TransactionInputs(); + let nonEmptyTag = false; if (reader.peekType(path) == "tagged") { let tag = reader.readTaggedTag(path); - if (tag != 258) throw new Error("Expected tag 258. Got " + tag); + if (tag != 258) { + throw new Error("Expected tag 258. Got " + tag); + } else { + nonEmptyTag = true; + } } - reader.readArray( + const { items, definiteEncoding } = reader.readArray( (reader, idx) => - ret.add( - TransactionInput.deserialize(reader, [ - ...path, - "TransactionInput#" + idx, - ]), - ), + TransactionInput.deserialize(reader, [ + ...path, + "TransactionInput#" + idx, + ]), path, ); + let ret = new TransactionInputs(definiteEncoding, nonEmptyTag); + ret.setItems(items); return ret; } serialize(writer: CBORWriter): void { - writer.writeTaggedTag(258); + if (this.nonEmptyTag) { + writer.writeTaggedTag(258); + } writer.writeArray(this.items, (writer, x) => x.serialize(writer)); } @@ -15337,9 +16773,11 @@ export class TransactionMetadatum { export class TransactionMetadatumLabels { private items: BigNum[]; + private definiteEncoding: boolean; - constructor(items: BigNum[]) { + constructor(items: BigNum[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): TransactionMetadatumLabels { @@ -15363,16 +16801,19 @@ export class TransactionMetadatumLabels { reader: CBORReader, path: string[], ): TransactionMetadatumLabels { - return new TransactionMetadatumLabels( - reader.readArray( - (reader, idx) => BigNum.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => BigNum.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new TransactionMetadatumLabels(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -15408,124 +16849,101 @@ export class TransactionMetadatumLabels { } } -export class TransactionOutput { - private _address: Address; - private _amount: Value; - private _plutus_data: PlutusData | undefined; - private _script_ref: ScriptRef | undefined; - - constructor( - address: Address, - amount: Value, - plutus_data: PlutusData | undefined, - script_ref: ScriptRef | undefined, - ) { - this._address = address; - this._amount = amount; - this._plutus_data = plutus_data; - this._script_ref = script_ref; - } +export enum TransactionOutputKind { + PreBabbageTransactionOutput = 0, + PostAlonzoTransactionOutput = 1, +} - address(): Address { - return this._address; - } +export type TransactionOutputVariant = + | { kind: 0; value: PreBabbageTransactionOutput } + | { kind: 1; value: PostAlonzoTransactionOutput }; - set_address(address: Address): void { - this._address = address; - } +export class TransactionOutput { + private variant: TransactionOutputVariant; - amount(): Value { - return this._amount; + constructor(variant: TransactionOutputVariant) { + this.variant = variant; } - set_amount(amount: Value): void { - this._amount = amount; + static new_pre_babbage_transaction_output( + pre_babbage_transaction_output: PreBabbageTransactionOutput, + ): TransactionOutput { + return new TransactionOutput({ + kind: 0, + value: pre_babbage_transaction_output, + }); } - plutus_data(): PlutusData | undefined { - return this._plutus_data; + static new_post_alonzo_transaction_output( + post_alonzo_transaction_output: PostAlonzoTransactionOutput, + ): TransactionOutput { + return new TransactionOutput({ + kind: 1, + value: post_alonzo_transaction_output, + }); } - set_plutus_data(plutus_data: PlutusData | undefined): void { - this._plutus_data = plutus_data; + as_pre_babbage_transaction_output(): PreBabbageTransactionOutput { + if (this.variant.kind == 0) return this.variant.value; + throw new Error("Incorrect cast"); } - script_ref(): ScriptRef | undefined { - return this._script_ref; + as_post_alonzo_transaction_output(): PostAlonzoTransactionOutput { + if (this.variant.kind == 1) return this.variant.value; + throw new Error("Incorrect cast"); } - set_script_ref(script_ref: ScriptRef | undefined): void { - this._script_ref = script_ref; + kind(): TransactionOutputKind { + return this.variant.kind; } static deserialize(reader: CBORReader, path: string[]): TransactionOutput { - let fields: any = {}; - reader.readMap((r) => { - let key = Number(r.readUint(path)); - switch (key) { - case 0: { - const new_path = [...path, "Address(address)"]; - fields.address = Address.deserialize(r, new_path); - break; - } - - case 1: { - const new_path = [...path, "Value(amount)"]; - fields.amount = Value.deserialize(r, new_path); - break; - } - - case 2: { - const new_path = [...path, "PlutusData(plutus_data)"]; - fields.plutus_data = PlutusData.deserialize(r, new_path); - break; - } - - case 3: { - const new_path = [...path, "ScriptRef(script_ref)"]; - fields.script_ref = ScriptRef.deserialize(r, new_path); - break; - } - } - }, path); + let tag = reader.peekType(path); + let variant: TransactionOutputVariant; - if (fields.address === undefined) - throw new Error( - "Value not provided for field 0 (address) (at " + path.join("/") + ")", - ); - let address = fields.address; - if (fields.amount === undefined) - throw new Error( - "Value not provided for field 1 (amount) (at " + path.join("/") + ")", - ); - let amount = fields.amount; + switch (tag) { + case "array": + variant = { + kind: TransactionOutputKind.PreBabbageTransactionOutput, + value: PreBabbageTransactionOutput.deserialize(reader, [ + ...path, + "PreBabbageTransactionOutput(pre_babbage_transaction_output)", + ]), + }; + break; - let plutus_data = fields.plutus_data; + case "map": + variant = { + kind: TransactionOutputKind.PostAlonzoTransactionOutput, + value: PostAlonzoTransactionOutput.deserialize(reader, [ + ...path, + "PostAlonzoTransactionOutput(post_alonzo_transaction_output)", + ]), + }; + break; - let script_ref = fields.script_ref; + default: + throw new Error( + "Unexpected subtype for TransactionOutput: " + + tag + + "(at " + + path.join("/") + + ")", + ); + } - return new TransactionOutput(address, amount, plutus_data, script_ref); + return new TransactionOutput(variant); } serialize(writer: CBORWriter): void { - let len = 4; - if (this._plutus_data === undefined) len -= 1; - if (this._script_ref === undefined) len -= 1; - writer.writeMapTag(len); - - writer.writeInt(0n); - this._address.serialize(writer); - - writer.writeInt(1n); - this._amount.serialize(writer); + switch (this.variant.kind) { + case 0: + this.variant.value.serialize(writer); + break; - if (this._plutus_data !== undefined) { - writer.writeInt(2n); - this._plutus_data.serialize(writer); - } - if (this._script_ref !== undefined) { - writer.writeInt(3n); - this._script_ref.serialize(writer); + case 1: + this.variant.value.serialize(writer); + break; } } @@ -15562,15 +16980,26 @@ export class TransactionOutput { } static new(address: Address, amount: Value): TransactionOutput { - return new TransactionOutput(address, amount, undefined, undefined); + const post_alonzo_transaction_output = new PostAlonzoTransactionOutput( + address, + amount, + undefined, + undefined, + ); + return new TransactionOutput({ + kind: 1, + value: post_alonzo_transaction_output, + }); } } export class TransactionOutputs { private items: TransactionOutput[]; + private definiteEncoding: boolean; - constructor(items: TransactionOutput[]) { + constructor(items: TransactionOutput[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): TransactionOutputs { @@ -15591,17 +17020,20 @@ export class TransactionOutputs { } static deserialize(reader: CBORReader, path: string[]): TransactionOutputs { - return new TransactionOutputs( - reader.readArray( - (reader, idx) => - TransactionOutput.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + TransactionOutput.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new TransactionOutputs(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -15642,7 +17074,7 @@ export class TransactionWitnessSet { private _native_scripts: NativeScripts | undefined; private _bootstraps: BootstrapWitnesses | undefined; private _plutus_scripts_v1: PlutusScripts | undefined; - private _plutus_data: PlutusList | undefined; + private _inner_plutus_data: PlutusSet | undefined; private _redeemers: Redeemers | undefined; private _plutus_scripts_v2: PlutusScripts | undefined; private _plutus_scripts_v3: PlutusScripts | undefined; @@ -15652,7 +17084,7 @@ export class TransactionWitnessSet { native_scripts: NativeScripts | undefined, bootstraps: BootstrapWitnesses | undefined, plutus_scripts_v1: PlutusScripts | undefined, - plutus_data: PlutusList | undefined, + inner_plutus_data: PlutusSet | undefined, redeemers: Redeemers | undefined, plutus_scripts_v2: PlutusScripts | undefined, plutus_scripts_v3: PlutusScripts | undefined, @@ -15661,7 +17093,7 @@ export class TransactionWitnessSet { this._native_scripts = native_scripts; this._bootstraps = bootstraps; this._plutus_scripts_v1 = plutus_scripts_v1; - this._plutus_data = plutus_data; + this._inner_plutus_data = inner_plutus_data; this._redeemers = redeemers; this._plutus_scripts_v2 = plutus_scripts_v2; this._plutus_scripts_v3 = plutus_scripts_v3; @@ -15699,12 +17131,12 @@ export class TransactionWitnessSet { this._plutus_scripts_v1 = plutus_scripts_v1; } - plutus_data(): PlutusList | undefined { - return this._plutus_data; + inner_plutus_data(): PlutusSet | undefined { + return this._inner_plutus_data; } - set_plutus_data(plutus_data: PlutusList | undefined): void { - this._plutus_data = plutus_data; + set_inner_plutus_data(inner_plutus_data: PlutusSet | undefined): void { + this._inner_plutus_data = inner_plutus_data; } redeemers(): Redeemers | undefined { @@ -15764,8 +17196,8 @@ export class TransactionWitnessSet { } case 4: { - const new_path = [...path, "PlutusList(plutus_data)"]; - fields.plutus_data = PlutusList.deserialize(r, new_path); + const new_path = [...path, "PlutusSet(inner_plutus_data)"]; + fields.inner_plutus_data = PlutusSet.deserialize(r, new_path); break; } @@ -15797,7 +17229,7 @@ export class TransactionWitnessSet { let plutus_scripts_v1 = fields.plutus_scripts_v1; - let plutus_data = fields.plutus_data; + let inner_plutus_data = fields.inner_plutus_data; let redeemers = fields.redeemers; @@ -15810,7 +17242,7 @@ export class TransactionWitnessSet { native_scripts, bootstraps, plutus_scripts_v1, - plutus_data, + inner_plutus_data, redeemers, plutus_scripts_v2, plutus_scripts_v3, @@ -15823,7 +17255,7 @@ export class TransactionWitnessSet { if (this._native_scripts === undefined) len -= 1; if (this._bootstraps === undefined) len -= 1; if (this._plutus_scripts_v1 === undefined) len -= 1; - if (this._plutus_data === undefined) len -= 1; + if (this._inner_plutus_data === undefined) len -= 1; if (this._redeemers === undefined) len -= 1; if (this._plutus_scripts_v2 === undefined) len -= 1; if (this._plutus_scripts_v3 === undefined) len -= 1; @@ -15844,9 +17276,9 @@ export class TransactionWitnessSet { writer.writeInt(3n); this._plutus_scripts_v1.serialize(writer); } - if (this._plutus_data !== undefined) { + if (this._inner_plutus_data !== undefined) { writer.writeInt(4n); - this._plutus_data.serialize(writer); + this._inner_plutus_data.serialize(writer); } if (this._redeemers !== undefined) { writer.writeInt(5n); @@ -15906,13 +17338,26 @@ export class TransactionWitnessSet { undefined, ); } + + plutus_data(): PlutusList | undefined { + return this.inner_plutus_data()?.as_list(); + } + + set_plutus_data(plutus_data: PlutusList): void { + this._inner_plutus_data = plutus_data.as_set(); + } } export class TransactionWitnessSets { private items: TransactionWitnessSet[]; + private definiteEncoding: boolean; - constructor(items: TransactionWitnessSet[]) { + constructor( + items: TransactionWitnessSet[], + definiteEncoding: boolean = true, + ) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): TransactionWitnessSets { @@ -15936,17 +17381,20 @@ export class TransactionWitnessSets { reader: CBORReader, path: string[], ): TransactionWitnessSets { - return new TransactionWitnessSets( - reader.readArray( - (reader, idx) => - TransactionWitnessSet.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => + TransactionWitnessSet.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new TransactionWitnessSets(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -16283,7 +17731,7 @@ export class UnitInterval { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -16306,7 +17754,9 @@ export class UnitInterval { } serializeInner(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._numerator.serialize(writer); this._denominator.serialize(writer); @@ -16464,7 +17914,7 @@ export class Update { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -16488,7 +17938,9 @@ export class Update { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._proposed_protocol_parameter_updates.serialize(writer); writer.writeInt(BigInt(this._epoch)); @@ -16683,7 +18135,7 @@ export class VRFCert { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -16700,7 +18152,9 @@ export class VRFCert { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); writer.writeBytes(this._output); writer.writeBytes(this._proof); @@ -16883,7 +18337,7 @@ export class Value { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -16904,7 +18358,9 @@ export class Value { } serializeRecord(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._coin.serialize(writer); if (this._multiasset == null) { @@ -17044,30 +18500,6 @@ export class Vkey { this._public_key = public_key; } - static deserialize(reader: CBORReader, path: string[]): Vkey { - let len = reader.readArrayTag(path); - - if (len != null && len < 1) { - throw new Error( - "Insufficient number of fields in record. Expected 1. Received " + - len + - "(at " + - path.join("/"), - ); - } - - const public_key_path = [...path, "PublicKey(public_key)"]; - let public_key = PublicKey.deserialize(reader, public_key_path); - - return new Vkey(public_key); - } - - serialize(writer: CBORWriter): void { - writer.writeArrayTag(1); - - this._public_key.serialize(writer); - } - // no-op free(): void {} @@ -17093,13 +18525,25 @@ export class Vkey { clone(path: string[]): Vkey { return Vkey.from_bytes(this.to_bytes(), path); } + + static deserialize(reader: CBORReader, path: string[]): Vkey { + const public_key_path = [...path, "PublicKey(public_key)"]; + let public_key = PublicKey.deserialize(reader, public_key_path); + return new Vkey(public_key); + } + + serialize(writer: CBORWriter): void { + this._public_key.serialize(writer); + } } export class Vkeys { private items: Vkey[]; + private definiteEncoding: boolean; - constructor(items: Vkey[]) { + constructor(items: Vkey[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): Vkeys { @@ -17120,16 +18564,19 @@ export class Vkeys { } static deserialize(reader: CBORReader, path: string[]): Vkeys { - return new Vkeys( - reader.readArray( - (reader, idx) => Vkey.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => Vkey.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new Vkeys(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -17193,7 +18640,7 @@ export class Vkeywitness { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -17210,7 +18657,9 @@ export class Vkeywitness { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); this._vkey.serialize(writer); this._signature.serialize(writer); @@ -17251,9 +18700,17 @@ export class Vkeywitness { export class Vkeywitnesses { private items: Vkeywitness[]; + private definiteEncoding: boolean; + private nonEmptyTag: boolean; + + private setItems(items: Vkeywitness[]) { + this.items = items; + } - constructor() { + constructor(definiteEncoding: boolean = true, nonEmptyTag: boolean = true) { this.items = []; + this.definiteEncoding = definiteEncoding; + this.nonEmptyTag = nonEmptyTag; } static new(): Vkeywitnesses { @@ -17285,23 +18742,29 @@ export class Vkeywitnesses { } static deserialize(reader: CBORReader, path: string[]): Vkeywitnesses { - let ret = new Vkeywitnesses(); + let nonEmptyTag = false; if (reader.peekType(path) == "tagged") { let tag = reader.readTaggedTag(path); - if (tag != 258) throw new Error("Expected tag 258. Got " + tag); + if (tag != 258) { + throw new Error("Expected tag 258. Got " + tag); + } else { + nonEmptyTag = true; + } } - reader.readArray( + const { items, definiteEncoding } = reader.readArray( (reader, idx) => - ret.add( - Vkeywitness.deserialize(reader, [...path, "Vkeywitness#" + idx]), - ), + Vkeywitness.deserialize(reader, [...path, "Vkeywitness#" + idx]), path, ); + let ret = new Vkeywitnesses(definiteEncoding, nonEmptyTag); + ret.setItems(items); return ret; } serialize(writer: CBORWriter): void { - writer.writeTaggedTag(258); + if (this.nonEmptyTag) { + writer.writeTaggedTag(258); + } writer.writeArray(this.items, (writer, x) => x.serialize(writer)); } @@ -17686,15 +19149,18 @@ export class Voter { }; break; + + default: + throw new Error( + "Unexpected tag for Voter: " + tag + "(at " + path.join("/") + ")", + ); } if (len == null) { reader.readBreak(); } - throw new Error( - "Unexpected tag for Voter: " + tag + "(at " + path.join("/") + ")", - ); + return new Voter(variant); } serialize(writer: CBORWriter): void { @@ -17818,9 +19284,11 @@ export class Voter { export class Voters { private items: Voter[]; + private definiteEncoding: boolean; - constructor(items: Voter[]) { + constructor(items: Voter[], definiteEncoding: boolean = true) { this.items = items; + this.definiteEncoding = definiteEncoding; } static new(): Voters { @@ -17841,16 +19309,19 @@ export class Voters { } static deserialize(reader: CBORReader, path: string[]): Voters { - return new Voters( - reader.readArray( - (reader, idx) => Voter.deserialize(reader, [...path, "Elem#" + idx]), - path, - ), + const { items, definiteEncoding } = reader.readArray( + (reader, idx) => Voter.deserialize(reader, [...path, "Elem#" + idx]), + path, ); + return new Voters(items, definiteEncoding); } serialize(writer: CBORWriter): void { - writer.writeArray(this.items, (writer, x) => x.serialize(writer)); + writer.writeArray( + this.items, + (writer, x) => x.serialize(writer), + this.definiteEncoding, + ); } // no-op @@ -17914,7 +19385,7 @@ export class VotingProcedure { if (len != null && len < 2) { throw new Error( - "Insufficient number of fields in record. Expected 2. Received " + + "Insufficient number of fields in record. Expected at least 2. Received " + len + "(at " + path.join("/"), @@ -17933,7 +19404,9 @@ export class VotingProcedure { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(2); + let arrayLen = 2; + + writer.writeArrayTag(arrayLen); serializeVoteKind(writer, this._vote); if (this._anchor == null) { @@ -18171,7 +19644,7 @@ export class VotingProposal { if (len != null && len < 4) { throw new Error( - "Insufficient number of fields in record. Expected 4. Received " + + "Insufficient number of fields in record. Expected at least 4. Received " + len + "(at " + path.join("/"), @@ -18205,7 +19678,9 @@ export class VotingProposal { } serialize(writer: CBORWriter): void { - writer.writeArrayTag(4); + let arrayLen = 4; + + writer.writeArrayTag(arrayLen); this._deposit.serialize(writer); this._reward_account.serialize(writer); @@ -18262,9 +19737,17 @@ export class VotingProposal { export class VotingProposals { private items: VotingProposal[]; + private definiteEncoding: boolean; + private nonEmptyTag: boolean; + + private setItems(items: VotingProposal[]) { + this.items = items; + } - constructor() { + constructor(definiteEncoding: boolean = true, nonEmptyTag: boolean = true) { this.items = []; + this.definiteEncoding = definiteEncoding; + this.nonEmptyTag = nonEmptyTag; } static new(): VotingProposals { @@ -18296,26 +19779,29 @@ export class VotingProposals { } static deserialize(reader: CBORReader, path: string[]): VotingProposals { - let ret = new VotingProposals(); + let nonEmptyTag = false; if (reader.peekType(path) == "tagged") { let tag = reader.readTaggedTag(path); - if (tag != 258) throw new Error("Expected tag 258. Got " + tag); + if (tag != 258) { + throw new Error("Expected tag 258. Got " + tag); + } else { + nonEmptyTag = true; + } } - reader.readArray( + const { items, definiteEncoding } = reader.readArray( (reader, idx) => - ret.add( - VotingProposal.deserialize(reader, [ - ...path, - "VotingProposal#" + idx, - ]), - ), + VotingProposal.deserialize(reader, [...path, "VotingProposal#" + idx]), path, ); + let ret = new VotingProposals(definiteEncoding, nonEmptyTag); + ret.setItems(items); return ret; } serialize(writer: CBORWriter): void { - writer.writeTaggedTag(258); + if (this.nonEmptyTag) { + writer.writeTaggedTag(258); + } writer.writeArray(this.items, (writer, x) => x.serialize(writer)); } @@ -18449,9 +19935,17 @@ export class Withdrawals { export class certificates { private items: Certificate[]; + private definiteEncoding: boolean; + private nonEmptyTag: boolean; + + private setItems(items: Certificate[]) { + this.items = items; + } - constructor() { + constructor(definiteEncoding: boolean = true, nonEmptyTag: boolean = true) { this.items = []; + this.definiteEncoding = definiteEncoding; + this.nonEmptyTag = nonEmptyTag; } static new(): certificates { @@ -18483,23 +19977,29 @@ export class certificates { } static deserialize(reader: CBORReader, path: string[]): certificates { - let ret = new certificates(); + let nonEmptyTag = false; if (reader.peekType(path) == "tagged") { let tag = reader.readTaggedTag(path); - if (tag != 258) throw new Error("Expected tag 258. Got " + tag); + if (tag != 258) { + throw new Error("Expected tag 258. Got " + tag); + } else { + nonEmptyTag = true; + } } - reader.readArray( + const { items, definiteEncoding } = reader.readArray( (reader, idx) => - ret.add( - Certificate.deserialize(reader, [...path, "Certificate#" + idx]), - ), + Certificate.deserialize(reader, [...path, "Certificate#" + idx]), path, ); + let ret = new certificates(definiteEncoding, nonEmptyTag); + ret.setItems(items); return ret; } serialize(writer: CBORWriter): void { - writer.writeTaggedTag(258); + if (this.nonEmptyTag) { + writer.writeTaggedTag(258); + } writer.writeArray(this.items, (writer, x) => x.serialize(writer)); } diff --git a/src/lib/cbor/reader.ts b/src/lib/cbor/reader.ts index 75dba64..69e8c64 100644 --- a/src/lib/cbor/reader.ts +++ b/src/lib/cbor/reader.ts @@ -1,3 +1,5 @@ +import { bytesToHex } from "../hex"; + type CBORType = | "uint" | "nint" @@ -77,7 +79,7 @@ export class CBORReader { if (this.peekType(path) == "uint") { return this.readBigInt(path); } else if (this.peekType(path) == "nint") { - return 1n - this.readBigInt(path); + return -1n - this.readBigInt(path); } else { throw new Error(`Unreachable (at ${path.join("/")})`); } @@ -90,7 +92,7 @@ export class CBORReader { } readString(path: string[]): string { - this.assertType(["bytes"], path); + this.assertType(["string"], path); let bytes = this.readByteString(path); return new TextDecoder().decode(bytes); } @@ -127,12 +129,13 @@ export class CBORReader { else this.readN(n, fn); } - readArray(readItem: (reader: CBORReader, idx: number) => T, path: string[]): T[] { + readArray(readItem: (reader: CBORReader, idx: number) => T, path: string[]): { items: T[], definiteEncoding: boolean} { let ret: T[] = []; - this.readMultiple(this.readArrayTag(path), (reader, idx) => + const len: number | null = this.readArrayTag(path); + this.readMultiple(len, (reader, idx) => ret.push(readItem(reader, idx)), ); - return ret; + return { items: ret, definiteEncoding: typeof(len) === "number"}; } readMap(readItem: (reader: CBORReader, idx: number) => T, path: string[]): T[] { @@ -194,8 +197,12 @@ export class CBORReader { // read cbor tag and return the tag value as number readTaggedTag(path: string[]): number { + return Number(this.readTaggedTagAsBigInt(path)); + } + + readTaggedTagAsBigInt(path: string[]): bigint { this.assertType(["tagged"], path); - return Number(this.readBigInt(path)); + return this.readBigInt(path); } assertType(expectedTypes: CBORType[], path: string[]) { @@ -210,8 +217,12 @@ export class CBORReader { private readLength(path: string[]): number | null { let tag = this.buffer[0]; let len = tag & 0b11111; - if (len == 0x1f) return null; - return Number(this.readBigInt(path)); + if (len == 0x1f) { + this.buffer = this.buffer.slice(1); + return null; + } else { + return Number(this.readBigInt(path)); + } } private readBigInt(path: string[]): bigint { @@ -255,6 +266,7 @@ export class CBORReader { this.buffer = this.buffer.slice(1); + // indefinite length if (len == 0x1f) { let chunks: Uint8Array[] = []; let chunk: Uint8Array; @@ -264,15 +276,24 @@ export class CBORReader { (chunk = this.readByteString(path)), chunks.push(chunk); } return concatUint8Array(chunks); + // definite length } else { - let n = Number(this.readBigInt(path)); - + let n: number; + // length follows in the next 1, 2, 4 or 8 bytes + if (len >= 0x18 && len <= 0x1b) { + const len_bytes: number = 1 << (len - 0x18); + n = Number(bigintFromBytes(len_bytes, this.buffer)); + this.buffer = this.buffer.slice(len_bytes); + // length is specified in the tag itself + } else { + n = len; + } let chunk = this.buffer.slice(0, n); this.buffer = this.buffer.slice(n); return chunk; + } } - } } export function bigintFromBytes(nBytes: number, stream: Uint8Array): bigint { diff --git a/src/lib/cbor/writer.ts b/src/lib/cbor/writer.ts index 1f85341..97674a6 100644 --- a/src/lib/cbor/writer.ts +++ b/src/lib/cbor/writer.ts @@ -1,5 +1,5 @@ import { GrowableBuffer } from "./growable-buffer"; -import { bytesToHex } from "../hex"; +import { bytesToHex, hexToBytes } from "../hex"; export class CBORWriter { private buffer: GrowableBuffer; @@ -56,7 +56,7 @@ export class CBORWriter { } writeStringValue(value: string) { - this.writeBytes(new TextEncoder().encode(value)); + this.writeBytesValue(new TextEncoder().encode(value)); } writeString(value: string) { @@ -71,11 +71,19 @@ export class CBORWriter { writeArray( array: { length: number } & Iterable, write: (writer: CBORWriter, value: T) => void, + definiteEncoding: boolean = true ) { - this.writeArrayTag(array.length); + this.writeArrayTag(definiteEncoding ? array.length : null); for (let item of array) { write(this, item); } + if (!definiteEncoding) { + this.buffer.pushByte(0xff); + } + } + + writeBreak() { + this.writeBytesValue(hexToBytes('0xff')); } writeMapTag(len: number | null) { diff --git a/tests/class-info.json b/tests/class-info.json index 19460e1..1a44a6f 100644 --- a/tests/class-info.json +++ b/tests/class-info.json @@ -24,7 +24,9 @@ "PlutusWitness", "PlutusWitnesses", "MintWitness", - "PlutusScriptSource" + "PlutusScriptSource", + "AuxiliaryDataShelleyMa", + "AuxiliaryDataPostAlonzo" ], "ignore_methods": { "Certificate": [ diff --git a/tests/serialization/serialization.test.ts b/tests/serialization/serialization.test.ts index c11092f..b82b652 100644 --- a/tests/serialization/serialization.test.ts +++ b/tests/serialization/serialization.test.ts @@ -6,6 +6,7 @@ import { test } from "@jest/globals"; import * as Out from "../../src/generated.ts" import { exit } from "node:process"; import { buildTestTable, retrieveTxsFromDir, roundtrip, writeChildErrorReport, writeExceptionReport, writeRoundtripErrorReport } from "./serialization_utils.ts"; +import { bytesToHex } from "../../src/lib/hex.ts"; // Locations for retrieved transactions const stagingPath = "tests/serialization/staging"; @@ -126,7 +127,7 @@ describe("roundtrip", () => { addToRegressionSuite(params); } // Now we run the actual jest tests - expect(roundtrip(Out[class_key], params.component.cbor)).toEqual(params.component.cbor); + expect(bytesToHex(roundtrip(Out[class_key], params.component.cbor))).toEqual(bytesToHex(params.component.cbor)); }); }) @@ -151,7 +152,7 @@ describe("roundtrip", () => { params.component.failed = true; writeExceptionReport(reportFile, params, err); } - expect(roundtrip(Out[class_key], params.component.cbor)).toEqual(params.component.cbor); + expect(bytesToHex(roundtrip(Out[class_key], params.component.cbor))).toEqual(bytesToHex(params.component.cbor)); }); }) diff --git a/tests/serialization/serialization_dev.test.ts b/tests/serialization/serialization_dev.test.ts index bd75573..26d0a00 100644 --- a/tests/serialization/serialization_dev.test.ts +++ b/tests/serialization/serialization_dev.test.ts @@ -3,6 +3,7 @@ import { RoundtripTestParameters, TransactionInfo } from "../test_types"; import { test } from "@jest/globals"; import * as Out from "../../src/generated.ts" import { buildTestTable, retrieveTxsFromDir, roundtrip} from "./serialization_utils.ts"; +import { bytesToHex } from "@noble/hashes/utils"; // Locations for retrieved transactions const devPath = "tests/reports/dev.txt"; @@ -58,7 +59,7 @@ describe("roundtrip", () => { params.component.failed = true; } // Now we run the actual jest tests - expect(roundtrip(Out[class_key], params.component.cbor)).toEqual(params.component.cbor); + expect(bytesToHex(roundtrip(Out[class_key], params.component.cbor))).toEqual(bytesToHex(params.component.cbor)); }); }) }); diff --git a/tests/serialization/serialization_utils.ts b/tests/serialization/serialization_utils.ts index 85b78f0..0c8eb9d 100644 --- a/tests/serialization/serialization_utils.ts +++ b/tests/serialization/serialization_utils.ts @@ -7,7 +7,7 @@ import { Schema } from "../../conway-cddl/codegen/types"; import { exit } from "node:process"; // Whether to log extraction messages or not -const traceExtraction = false; +const traceExtraction = true; const extractLog = traceExtraction ? (...args : any) => console.log(...args) : () => { ; }; // Types we are not interested in (or that are not supported) @@ -24,6 +24,8 @@ const fieldsBlacklist = new Set([ "plutus_scripts_v1", "plutus_scripts_v2", "plutus_scripts_v3", + "script_pubkey", + "inner_plutus_data" ]) export function retrieveTxsFromDir(path: string): Array { @@ -155,7 +157,7 @@ function explodeValue(key: string, value: any, schema: Schema, schemata: any, ch break; case "tagged_record": { // sum types - let tag: number = value.kind().valueOf(); + let tag: number = value.kind().valueOf(); let variant = schema.variants.find((v) => v.tag == tag) extractLog("variant", variant); if (variant && variant.value && schemata[variant.value]) { @@ -199,16 +201,25 @@ function explodeValue(key: string, value: any, schema: Schema, schemata: any, ch } break; case "array": - for (let index = 0; index < value.len(); index++) { - const {sub: elemValue, subPath: newComponentPath } = getElem(value, index, `${key}[${index}]`, schema.item, componentPath); - if (elemValue && schemata[schema.item]) { - extractLog(`Elem index: ${index}\nElem type: ${schema.item}\nPath: ${newComponentPath}`); - let grandchildren = []; - explodeValue(`${key}[${index}]`, elemValue, schemata[schema.item], schemata, grandchildren, newComponentPath) - children.push({ type: schema.item, key: key, path: newComponentPath, children: grandchildren, cbor: elemValue.to_bytes(), failed: false}); + if (schema.item) { + for (let index = 0; index < value.len(); index++) { + const {sub: elemValue, subPath: newComponentPath } = getElem(value, index, `${key}[${index}]`, schema.item, componentPath); + if (elemValue && schemata[schema.item]) { + extractLog(`Elem index: ${index}\nElem type: ${schema.item}\nPath: ${newComponentPath}`); + let grandchildren = []; + explodeValue(`${key}[${index}]`, elemValue, schemata[schema.item], schemata, grandchildren, newComponentPath) + children.push({ type: schema.item, key: key, path: newComponentPath, children: grandchildren, cbor: elemValue.to_bytes(), failed: false}); + } } } break; + case "union": { + // for unions we don't extract the children + // NOTE: The reason we don't do it is that there doesn't seem to be a + // common interface in CSL for interacting with a union's variants + extractLog("Found a union while extracting, ignoring..."); + break; + } case "enum": extractLog("Found an enum while extracting. Ignoring...") break; // enums don't have subcomponents