From 70cf762dedd8380a78df0f9aa0b80d9a011ef617 Mon Sep 17 00:00:00 2001
From: jared <>
Date: Wed, 28 Feb 2024 20:01:10 -0700
Subject: [PATCH 1/4] Refactored `src/Tests/*`
---
src/Tests/{ => Prelude}/BoolInstances-test.ts | 4 ++--
src/Tests/{ => Prelude}/IntegerInstances-test.ts | 4 ++--
src/Tests/{ => Prelude}/MaybeInstances-test.ts | 4 ++--
src/Tests/{ => V1}/AddressInstances-test.ts | 6 +++---
src/Tests/{ => V1}/CredentialInstances-test.ts | 4 ++--
src/Tests/{ => V1}/DatumHashInstances-test.ts | 4 ++--
src/Tests/{ => V1}/DatumInstances-test.ts | 2 +-
src/Tests/{ => V1}/IntervalInstances-test.ts | 4 ++--
src/Tests/{ => V1}/LedgerBytesInstances-test.ts | 4 ++--
src/Tests/{ => V1}/PubKeyHashInstances-test.ts | 4 ++--
src/Tests/{ => V1}/ScriptHashInstances-test.ts | 4 ++--
.../{ => V1}/StakingCredentialInstances-test.ts | 4 ++--
src/Tests/{ => V1}/TxIdInstances-test.ts | 4 ++--
src/Tests/{ => V1}/TxOutRefInstances-test.ts | 4 ++--
src/Tests/{ => V1}/ValueInstances-test.ts | 8 ++++----
src/Tests/{ => V2}/OutputDatumInstances-test.ts | 12 ++++++------
src/Tests/{ => V2}/TxInInfoInstances-test.ts | 10 +++++-----
src/Tests/{ => V2}/TxOutInstances-test.ts | 16 ++++++++--------
18 files changed, 51 insertions(+), 51 deletions(-)
rename src/Tests/{ => Prelude}/BoolInstances-test.ts (92%)
rename src/Tests/{ => Prelude}/IntegerInstances-test.ts (93%)
rename src/Tests/{ => Prelude}/MaybeInstances-test.ts (96%)
rename src/Tests/{ => V1}/AddressInstances-test.ts (98%)
rename src/Tests/{ => V1}/CredentialInstances-test.ts (98%)
rename src/Tests/{ => V1}/DatumHashInstances-test.ts (97%)
rename src/Tests/{ => V1}/DatumInstances-test.ts (67%)
rename src/Tests/{ => V1}/IntervalInstances-test.ts (99%)
rename src/Tests/{ => V1}/LedgerBytesInstances-test.ts (96%)
rename src/Tests/{ => V1}/PubKeyHashInstances-test.ts (97%)
rename src/Tests/{ => V1}/ScriptHashInstances-test.ts (97%)
rename src/Tests/{ => V1}/StakingCredentialInstances-test.ts (98%)
rename src/Tests/{ => V1}/TxIdInstances-test.ts (97%)
rename src/Tests/{ => V1}/TxOutRefInstances-test.ts (97%)
rename src/Tests/{ => V1}/ValueInstances-test.ts (98%)
rename src/Tests/{ => V2}/OutputDatumInstances-test.ts (94%)
rename src/Tests/{ => V2}/TxInInfoInstances-test.ts (94%)
rename src/Tests/{ => V2}/TxOutInstances-test.ts (91%)
diff --git a/src/Tests/BoolInstances-test.ts b/src/Tests/Prelude/BoolInstances-test.ts
similarity index 92%
rename from src/Tests/BoolInstances-test.ts
rename to src/Tests/Prelude/BoolInstances-test.ts
index ed7310a..b8ea47a 100644
--- a/src/Tests/BoolInstances-test.ts
+++ b/src/Tests/Prelude/BoolInstances-test.ts
@@ -1,10 +1,10 @@
// // Tests for the instances for `Bool`
import * as Prelude from "prelude";
-import * as PreludeInstances from "../Lib/Prelude/Instances.js";
+import * as PreludeInstances from "../../Lib/Prelude/Instances.js";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
describe("Bool tests", () => {
diff --git a/src/Tests/IntegerInstances-test.ts b/src/Tests/Prelude/IntegerInstances-test.ts
similarity index 93%
rename from src/Tests/IntegerInstances-test.ts
rename to src/Tests/Prelude/IntegerInstances-test.ts
index e7f41f6..0aca364 100644
--- a/src/Tests/IntegerInstances-test.ts
+++ b/src/Tests/Prelude/IntegerInstances-test.ts
@@ -1,10 +1,10 @@
// Tests for the instances for `Integer`
import * as Prelude from "prelude";
-import * as PreludeInstances from "../Lib/Prelude/Instances.js";
+import * as PreludeInstances from "../../Lib/Prelude/Instances.js";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
describe("Integer tests", () => {
diff --git a/src/Tests/MaybeInstances-test.ts b/src/Tests/Prelude/MaybeInstances-test.ts
similarity index 96%
rename from src/Tests/MaybeInstances-test.ts
rename to src/Tests/Prelude/MaybeInstances-test.ts
index 512d403..68c5915 100644
--- a/src/Tests/MaybeInstances-test.ts
+++ b/src/Tests/Prelude/MaybeInstances-test.ts
@@ -1,10 +1,10 @@
// // Tests for the instances for `Maybe`
import * as Prelude from "prelude";
-import * as PreludeInstances from "../Lib/Prelude/Instances.js";
+import * as PreludeInstances from "../../Lib/Prelude/Instances.js";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
export function fcMaybe(
diff --git a/src/Tests/AddressInstances-test.ts b/src/Tests/V1/AddressInstances-test.ts
similarity index 98%
rename from src/Tests/AddressInstances-test.ts
rename to src/Tests/V1/AddressInstances-test.ts
index f60038c..7673159 100644
--- a/src/Tests/AddressInstances-test.ts
+++ b/src/Tests/V1/AddressInstances-test.ts
@@ -1,15 +1,15 @@
// Tests for the instances for `Address`
-import * as V1 from "../Lib/V1.js";
+import * as V1 from "../../Lib/V1.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
import * as TestCredential from "./CredentialInstances-test.js";
import * as TestStakingCredential from "./StakingCredentialInstances-test.js";
-import * as TestMaybe from "./MaybeInstances-test.js";
+import * as TestMaybe from "../Prelude/MaybeInstances-test.js";
const pubKeyHash1 = Prelude.fromJust(
V1.pubKeyHashFromBytes(
diff --git a/src/Tests/CredentialInstances-test.ts b/src/Tests/V1/CredentialInstances-test.ts
similarity index 98%
rename from src/Tests/CredentialInstances-test.ts
rename to src/Tests/V1/CredentialInstances-test.ts
index 8d5467e..22f4aa7 100644
--- a/src/Tests/CredentialInstances-test.ts
+++ b/src/Tests/V1/CredentialInstances-test.ts
@@ -1,10 +1,10 @@
// // Tests for the instances for `Credential`
-import * as V1 from "../Lib/V1.js";
+import * as V1 from "../../Lib/V1.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
import * as TestPubKeyHash from "./PubKeyHashInstances-test.js";
diff --git a/src/Tests/DatumHashInstances-test.ts b/src/Tests/V1/DatumHashInstances-test.ts
similarity index 97%
rename from src/Tests/DatumHashInstances-test.ts
rename to src/Tests/V1/DatumHashInstances-test.ts
index 4a84ecd..40d8c44 100644
--- a/src/Tests/DatumHashInstances-test.ts
+++ b/src/Tests/V1/DatumHashInstances-test.ts
@@ -1,10 +1,10 @@
// Tests for the instances for `DatumHash`
-import * as V1 from "../Lib/V1.js";
+import * as V1 from "../../Lib/V1.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
// `datumHash1` is distinct from `datumHash2`
diff --git a/src/Tests/DatumInstances-test.ts b/src/Tests/V1/DatumInstances-test.ts
similarity index 67%
rename from src/Tests/DatumInstances-test.ts
rename to src/Tests/V1/DatumInstances-test.ts
index 54c7067..cfe43a5 100644
--- a/src/Tests/DatumInstances-test.ts
+++ b/src/Tests/V1/DatumInstances-test.ts
@@ -1,5 +1,5 @@
// Alias the generator for `Datum` since `Datum` is a type alias for
// `PlutusData`
-import * as TestPlutusData from "./PlutusDataInstances-test.js";
+import * as TestPlutusData from "../PlutusDataInstances-test.js";
export const fcDatum = TestPlutusData.fcPlutusData;
diff --git a/src/Tests/IntervalInstances-test.ts b/src/Tests/V1/IntervalInstances-test.ts
similarity index 99%
rename from src/Tests/IntervalInstances-test.ts
rename to src/Tests/V1/IntervalInstances-test.ts
index a966e08..9662ca1 100644
--- a/src/Tests/IntervalInstances-test.ts
+++ b/src/Tests/V1/IntervalInstances-test.ts
@@ -1,10 +1,10 @@
// Tests for the instances for various types in the `V1/Interval.js` file
-import * as V1 from "../Lib/V1.js";
+import * as V1 from "../../Lib/V1.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
export function fcExtended(
diff --git a/src/Tests/LedgerBytesInstances-test.ts b/src/Tests/V1/LedgerBytesInstances-test.ts
similarity index 96%
rename from src/Tests/LedgerBytesInstances-test.ts
rename to src/Tests/V1/LedgerBytesInstances-test.ts
index 911b89e..972b787 100644
--- a/src/Tests/LedgerBytesInstances-test.ts
+++ b/src/Tests/V1/LedgerBytesInstances-test.ts
@@ -1,9 +1,9 @@
// Tests for the instances for `LedgerBytes`
-import * as V1 from "../Lib/V1.js";
+import * as V1 from "../../Lib/V1.js";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
describe("LedgerBytes tests", () => {
diff --git a/src/Tests/PubKeyHashInstances-test.ts b/src/Tests/V1/PubKeyHashInstances-test.ts
similarity index 97%
rename from src/Tests/PubKeyHashInstances-test.ts
rename to src/Tests/V1/PubKeyHashInstances-test.ts
index 068a054..0f886b0 100644
--- a/src/Tests/PubKeyHashInstances-test.ts
+++ b/src/Tests/V1/PubKeyHashInstances-test.ts
@@ -1,10 +1,10 @@
// Tests for the instances for `PubKeyHash`
-import * as V1 from "../Lib/V1.js";
+import * as V1 from "../../Lib/V1.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
// `pubKeyHash1` is distinct from `pubKeyHash2`
diff --git a/src/Tests/ScriptHashInstances-test.ts b/src/Tests/V1/ScriptHashInstances-test.ts
similarity index 97%
rename from src/Tests/ScriptHashInstances-test.ts
rename to src/Tests/V1/ScriptHashInstances-test.ts
index 5488d1d..1250484 100644
--- a/src/Tests/ScriptHashInstances-test.ts
+++ b/src/Tests/V1/ScriptHashInstances-test.ts
@@ -1,10 +1,10 @@
// Tests for the instances for `ScriptHash`
-import * as V1 from "../Lib/V1.js";
+import * as V1 from "../../Lib/V1.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
// `scriptHash1` is distinct from `scriptHash2`
diff --git a/src/Tests/StakingCredentialInstances-test.ts b/src/Tests/V1/StakingCredentialInstances-test.ts
similarity index 98%
rename from src/Tests/StakingCredentialInstances-test.ts
rename to src/Tests/V1/StakingCredentialInstances-test.ts
index cddf59b..1cd03f4 100644
--- a/src/Tests/StakingCredentialInstances-test.ts
+++ b/src/Tests/V1/StakingCredentialInstances-test.ts
@@ -1,10 +1,10 @@
// Tests for the instances for `StakingCredential`
-import * as V1 from "../Lib/V1.js";
+import * as V1 from "../../Lib/V1.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
import * as TestCredential from "./CredentialInstances-test.js";
diff --git a/src/Tests/TxIdInstances-test.ts b/src/Tests/V1/TxIdInstances-test.ts
similarity index 97%
rename from src/Tests/TxIdInstances-test.ts
rename to src/Tests/V1/TxIdInstances-test.ts
index d3ba6b3..d1277a8 100644
--- a/src/Tests/TxIdInstances-test.ts
+++ b/src/Tests/V1/TxIdInstances-test.ts
@@ -1,10 +1,10 @@
// Tests for the instances for `TxId`
-import * as V1 from "../Lib/V1.js";
+import * as V1 from "../../Lib/V1.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
// `txId1` is distinct from `txId2`
diff --git a/src/Tests/TxOutRefInstances-test.ts b/src/Tests/V1/TxOutRefInstances-test.ts
similarity index 97%
rename from src/Tests/TxOutRefInstances-test.ts
rename to src/Tests/V1/TxOutRefInstances-test.ts
index 8c47c20..0dc2572 100644
--- a/src/Tests/TxOutRefInstances-test.ts
+++ b/src/Tests/V1/TxOutRefInstances-test.ts
@@ -1,10 +1,10 @@
// Tests for the instances for `TxOutRef`
-import * as V1 from "../Lib/V1.js";
+import * as V1 from "../../Lib/V1.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
import * as TestTxId from "./TxIdInstances-test.js";
diff --git a/src/Tests/ValueInstances-test.ts b/src/Tests/V1/ValueInstances-test.ts
similarity index 98%
rename from src/Tests/ValueInstances-test.ts
rename to src/Tests/V1/ValueInstances-test.ts
index 3acbe8a..fbc88cd 100644
--- a/src/Tests/ValueInstances-test.ts
+++ b/src/Tests/V1/ValueInstances-test.ts
@@ -1,12 +1,12 @@
// Tests for the instances for various types in the `V1/Value.js` file
-import * as V1 from "../Lib/V1.js";
-import * as LbAssocMap from "../Lib/AssocMap.js";
+import * as V1 from "../../Lib/V1.js";
+import * as LbAssocMap from "../../Lib/AssocMap.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
-import * as TestAssocMap from "./AssocMap-test.js";
+import * as TestUtils from "../TestUtils.js";
+import * as TestAssocMap from "../AssocMap-test.js";
import fc from "fast-check";
// `currencySymbol1` is distinct from `currencySymbol2`
diff --git a/src/Tests/OutputDatumInstances-test.ts b/src/Tests/V2/OutputDatumInstances-test.ts
similarity index 94%
rename from src/Tests/OutputDatumInstances-test.ts
rename to src/Tests/V2/OutputDatumInstances-test.ts
index cb32bae..9378c64 100644
--- a/src/Tests/OutputDatumInstances-test.ts
+++ b/src/Tests/V2/OutputDatumInstances-test.ts
@@ -1,16 +1,16 @@
// Tests for the instances for `OutputDatum`
-import * as V1 from "../Lib/V1.js";
-import * as V2 from "../Lib/V2.js";
-import * as LbPlutusData from "../Lib/PlutusData.js";
+import * as V1 from "../../Lib/V1.js";
+import * as V2 from "../../Lib/V2.js";
+import * as LbPlutusData from "../../Lib/PlutusData.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
-import * as TestDatum from "./DatumInstances-test.js";
-import * as TestDatumHash from "./DatumHashInstances-test.js";
+import * as TestDatum from "../V1/DatumInstances-test.js";
+import * as TestDatumHash from "../V1/DatumHashInstances-test.js";
export const datumHash1: V1.DatumHash = Prelude.fromJust(
V1.datumHashFromBytes(
diff --git a/src/Tests/TxInInfoInstances-test.ts b/src/Tests/V2/TxInInfoInstances-test.ts
similarity index 94%
rename from src/Tests/TxInInfoInstances-test.ts
rename to src/Tests/V2/TxInInfoInstances-test.ts
index 12bc8c0..bcda740 100644
--- a/src/Tests/TxInInfoInstances-test.ts
+++ b/src/Tests/V2/TxInInfoInstances-test.ts
@@ -1,15 +1,15 @@
// Tests for the instances for `TxInInfo`
-import * as LbAssocMap from "../Lib/AssocMap.js";
-import * as V1 from "../Lib/V1.js";
-import * as V2 from "../Lib/V2.js";
+import * as LbAssocMap from "../../Lib/AssocMap.js";
+import * as V1 from "../../Lib/V1.js";
+import * as V2 from "../../Lib/V2.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
-import * as TestTxOutRef from "./TxOutRefInstances-test.js";
+import * as TestTxOutRef from "../V1/TxOutRefInstances-test.js";
import * as TestTxOut from "./TxOutInstances-test.js";
export function fcTxInInfo(): fc.Arbitrary {
diff --git a/src/Tests/TxOutInstances-test.ts b/src/Tests/V2/TxOutInstances-test.ts
similarity index 91%
rename from src/Tests/TxOutInstances-test.ts
rename to src/Tests/V2/TxOutInstances-test.ts
index 1867940..3bc31d6 100644
--- a/src/Tests/TxOutInstances-test.ts
+++ b/src/Tests/V2/TxOutInstances-test.ts
@@ -1,19 +1,19 @@
// Tests for the instances for `TxOut`
-import * as LbAssocMap from "../Lib/AssocMap.js";
-import * as V1 from "../Lib/V1.js";
-import * as V2 from "../Lib/V2.js";
+import * as LbAssocMap from "../../Lib/AssocMap.js";
+import * as V1 from "../../Lib/V1.js";
+import * as V2 from "../../Lib/V2.js";
import * as Prelude from "prelude";
import { describe, it } from "node:test";
-import * as TestUtils from "./TestUtils.js";
+import * as TestUtils from "../TestUtils.js";
import fc from "fast-check";
-import * as TestAddress from "./AddressInstances-test.js";
-import * as TestValue from "./ValueInstances-test.js";
+import * as TestAddress from "../V1/AddressInstances-test.js";
+import * as TestValue from "../V1/ValueInstances-test.js";
import * as TestOutputDatum from "./OutputDatumInstances-test.js";
-import * as TestMaybe from "./MaybeInstances-test.js";
-import * as TestScriptHash from "./ScriptHashInstances-test.js";
+import * as TestMaybe from "../Prelude/MaybeInstances-test.js";
+import * as TestScriptHash from "../V1/ScriptHashInstances-test.js";
export function fcTxOut(): fc.Arbitrary {
return fc.record({
From e593387de144fee0f9bcb050cf765811a9d7d84c Mon Sep 17 00:00:00 2001
From: jared <>
Date: Wed, 28 Feb 2024 20:38:45 -0700
Subject: [PATCH 2/4] Added `V1.TxOut` + tests
---
src/Lib/V1/Contexts.hs | 3 +
src/Lib/V1/Tx.ts | 117 +++++++++++++++++
src/Tests/V1/TxOutInstances-test.ts | 187 ++++++++++++++++++++++++++++
3 files changed, 307 insertions(+)
create mode 100644 src/Lib/V1/Contexts.hs
create mode 100644 src/Tests/V1/TxOutInstances-test.ts
diff --git a/src/Lib/V1/Contexts.hs b/src/Lib/V1/Contexts.hs
new file mode 100644
index 0000000..0f14a12
--- /dev/null
+++ b/src/Lib/V1/Contexts.hs
@@ -0,0 +1,3 @@
+/**
+ * @see {@link https://github.com/IntersectMBO/plutus/blob/1.16.0.0/plutus-ledger-api/src/PlutusLedgerApi/V1/Contexts.hs}
+ */
diff --git a/src/Lib/V1/Tx.ts b/src/Lib/V1/Tx.ts
index 4b0e062..f4815c7 100644
--- a/src/Lib/V1/Tx.ts
+++ b/src/Lib/V1/Tx.ts
@@ -10,6 +10,14 @@ import * as Prelude from "prelude";
import { JsonError } from "prelude";
import * as LbBytes from "./Bytes.js";
+import type { Value } from "./Value.js";
+import type { DatumHash } from "./Scripts.js";
+import type { Address } from "./Address.js";
+
+import * as LbValue from "./Value.js";
+import * as LbScripts from "./Scripts.js";
+import * as LbAddress from "./Address.js";
+
/**
* {@link TxId} is a transaction id i.e., the hash of a transaction. 32 bytes.
*
@@ -157,3 +165,112 @@ export const isPlutusDataTxOutRef: IsPlutusData = {
throw new IsPlutusDataError("Invalid data");
},
};
+
+//////////////////////////////////////////////////
+
+/**
+ * {@link TxOut} a transaction output consisting of a target address, a value,
+ * and optionally a datum hash.
+ *
+ * @see {@link https://github.com/IntersectMBO/plutus/blob/1.16.0.0/plutus-ledger-api/src/PlutusLedgerApi/V1/Tx.hs#L102-L110}
+ */
+export type TxOut = {
+ txOutAddress: Address;
+ txOutValue: Value;
+ txOutDatumHash: Maybe;
+};
+
+/**
+ * {@link Eq} instance for {@link TxOut}
+ */
+export const eqTxOut: Eq = {
+ eq: (l, r) => {
+ return LbAddress.eqAddress.eq(l.txOutAddress, r.txOutAddress) &&
+ LbValue.eqValue.eq(l.txOutValue, r.txOutValue) &&
+ Prelude.eqMaybe(LbScripts.eqDatumHash).eq(
+ l.txOutDatumHash,
+ r.txOutDatumHash,
+ );
+ },
+ neq: (l, r) => {
+ return LbAddress.eqAddress.neq(l.txOutAddress, r.txOutAddress) ||
+ LbValue.eqValue.neq(l.txOutValue, r.txOutValue) ||
+ Prelude.eqMaybe(LbScripts.eqDatumHash).neq(
+ l.txOutDatumHash,
+ r.txOutDatumHash,
+ );
+ },
+};
+
+/**
+ * {@link Json} instance for {@link TxOut}
+ */
+export const jsonTxOut: Json = {
+ toJson: (txOut) => {
+ return {
+ "address": LbAddress.jsonAddress.toJson(txOut.txOutAddress),
+ "datum_hash": Prelude.jsonMaybe(LbScripts.jsonDatumHash).toJson(
+ txOut.txOutDatumHash,
+ ),
+ "value": LbValue.jsonValue.toJson(txOut.txOutValue),
+ };
+ },
+ fromJson: (value) => {
+ const txOutAddress = Prelude.caseFieldWithValue(
+ "address",
+ LbAddress.jsonAddress.fromJson,
+ value,
+ );
+ const txOutValue = Prelude.caseFieldWithValue(
+ "value",
+ LbValue.jsonValue.fromJson,
+ value,
+ );
+
+ const txOutDatumHash = Prelude.caseFieldWithValue(
+ "datum_hash",
+ Prelude.jsonMaybe(LbScripts.jsonDatumHash).fromJson,
+ value,
+ );
+ return { txOutAddress, txOutDatumHash, txOutValue };
+ },
+};
+
+/**
+ * {@link IsPlutusData} instance for {@link TxOut}
+ */
+export const isPlutusDataTxOut: IsPlutusData = {
+ toData: (txOut) => {
+ return {
+ fields: [0n, [
+ LbAddress.isPlutusDataAddress.toData(txOut.txOutAddress),
+ LbValue.isPlutusDataValue.toData(txOut.txOutValue),
+ PreludeInstances.isPlutusDataMaybe(LbScripts.isPlutusDataDatumHash)
+ .toData(txOut.txOutDatumHash),
+ ]],
+ name: "Constr",
+ };
+ },
+ fromData: (plutusData) => {
+ switch (plutusData.name) {
+ case "Constr":
+ if (plutusData.fields[0] === 0n && plutusData.fields[1].length === 3) {
+ return {
+ txOutAddress: LbAddress.isPlutusDataAddress.fromData(
+ plutusData.fields[1][0]!,
+ ),
+ txOutDatumHash: PreludeInstances.isPlutusDataMaybe(
+ LbScripts.isPlutusDataDatumHash,
+ ).fromData(plutusData.fields[1][2]!),
+ txOutValue: LbValue.isPlutusDataValue.fromData(
+ plutusData.fields[1][1]!,
+ ),
+ };
+ }
+ break;
+ default:
+ break;
+ }
+ throw new IsPlutusDataError("Invalid data");
+ },
+};
diff --git a/src/Tests/V1/TxOutInstances-test.ts b/src/Tests/V1/TxOutInstances-test.ts
new file mode 100644
index 0000000..7560228
--- /dev/null
+++ b/src/Tests/V1/TxOutInstances-test.ts
@@ -0,0 +1,187 @@
+// Tests for the instances for `TxOut`
+import * as LbAssocMap from "../../Lib/AssocMap.js";
+import * as V1 from "../../Lib/V1.js";
+import * as Prelude from "prelude";
+import * as PreludeInstances from "../../Lib/Prelude/Instances.js";
+
+import { describe, it } from "node:test";
+
+import * as TestUtils from "../TestUtils.js";
+import fc from "fast-check";
+
+import * as TestAddress from "./AddressInstances-test.js";
+import * as TestValue from "./ValueInstances-test.js";
+import * as TestMaybe from "../Prelude/MaybeInstances-test.js";
+import * as TestDatumHash from "./DatumHashInstances-test.js";
+
+export function fcTxOut(): fc.Arbitrary {
+ return fc.record({
+ txOutAddress: TestAddress.fcAddress(),
+ txOutValue: TestValue.fcValue(),
+ txOutDatumHash: TestMaybe.fcMaybe(TestDatumHash.fcDatumHash()),
+ }) as fc.Arbitrary;
+}
+
+const pubKeyHash1 = Prelude.fromJust(
+ V1.pubKeyHashFromBytes(
+ Uint8Array.from([
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ ]),
+ ),
+);
+
+const credential1: V1.Credential = {
+ name: "PubKeyCredential",
+ fields: pubKeyHash1,
+};
+const address1: V1.Address = {
+ addressCredential: credential1,
+ addressStakingCredential: { name: "Nothing" },
+};
+
+const value1: V1.Value = LbAssocMap.fromList([]);
+
+const maybeDatumHash1: Prelude.Maybe = {
+ name: `Just`,
+ fields: TestDatumHash.datumHash1,
+};
+const maybeDatumHash2: Prelude.Maybe = { name: `Nothing` };
+
+const txOut1: V1.TxOut = {
+ txOutAddress: address1,
+ txOutValue: value1,
+ txOutDatumHash: maybeDatumHash1,
+};
+
+const txOut2: V1.TxOut = {
+ txOutAddress: address1,
+ txOutValue: value1,
+ txOutDatumHash: maybeDatumHash2,
+};
+
+describe("TxOut tests", () => {
+ describe("Eq TxOut tests", () => {
+ const dict = V1.eqTxOut;
+ TestUtils.eqIt(dict, txOut1, txOut1, true);
+ TestUtils.neqIt(dict, txOut1, txOut1, false);
+
+ TestUtils.eqIt(dict, txOut2, txOut2, true);
+ TestUtils.neqIt(dict, txOut2, txOut2, false);
+
+ TestUtils.eqIt(dict, txOut2, txOut1, false);
+ TestUtils.neqIt(dict, txOut2, txOut1, true);
+
+ it(`eq is not neq property based tests`, () => {
+ fc.assert(
+ fc.property(
+ fcTxOut(),
+ fcTxOut(),
+ (l, r) => {
+ TestUtils.negationTest(dict, l, r);
+ },
+ ),
+ { examples: [] },
+ );
+ });
+ });
+
+ describe("Json TxOut tests", () => {
+ TestUtils.toJsonAndFromJsonIt(V1.jsonTxOut, txOut1, {
+ address: V1.jsonAddress.toJson(address1),
+ datum_hash: Prelude.jsonMaybe(V1.jsonDatumHash).toJson(maybeDatumHash1),
+ value: [],
+ });
+
+ TestUtils.toJsonAndFromJsonIt(V1.jsonTxOut, txOut2, {
+ address: V1.jsonAddress.toJson(address1),
+ datum_hash: Prelude.jsonMaybe(V1.jsonDatumHash).toJson(maybeDatumHash2),
+ value: [],
+ });
+
+ it(`toJson/fromJson property based tests`, () => {
+ fc.assert(
+ fc.property(
+ fcTxOut(),
+ (data) => {
+ TestUtils.toJsonFromJsonRoundTrip(V1.jsonTxOut, data);
+ },
+ ),
+ { examples: [] },
+ );
+ });
+ });
+
+ describe("IsPlutusData TxOut tests", () => {
+ TestUtils.isPlutusDataIt(
+ V1.isPlutusDataTxOut,
+ txOut1,
+ {
+ name: "Constr",
+ fields: [0n, [
+ V1.isPlutusDataAddress.toData(address1),
+ V1.isPlutusDataValue.toData(value1),
+ PreludeInstances.isPlutusDataMaybe(V1.isPlutusDataDatumHash).toData(
+ maybeDatumHash1,
+ ),
+ ]],
+ },
+ );
+
+ TestUtils.isPlutusDataIt(
+ V1.isPlutusDataTxOut,
+ txOut2,
+ {
+ name: "Constr",
+ fields: [0n, [
+ V1.isPlutusDataAddress.toData(address1),
+ V1.isPlutusDataValue.toData(value1),
+ PreludeInstances.isPlutusDataMaybe(V1.isPlutusDataDatumHash).toData(
+ maybeDatumHash2,
+ ),
+ ]],
+ },
+ );
+
+ it(`toData/fromData property based tests`, () => {
+ fc.assert(
+ fc.property(
+ fcTxOut(),
+ (data) => {
+ TestUtils.isPlutusDataRoundTrip(
+ V1.isPlutusDataTxOut,
+ data,
+ );
+ },
+ ),
+ { examples: [] },
+ );
+ });
+ });
+});
From 18e360dbca04893679139d7c32122e490e9758d1 Mon Sep 17 00:00:00 2001
From: jared <>
Date: Thu, 29 Feb 2024 01:30:01 -0700
Subject: [PATCH 3/4] Added TxInfo and its required instances + tests
---
src/Lib/AssocMap.ts | 2 +-
src/Lib/V1.ts | 2 +
src/Lib/V1/Contexts.hs | 3 -
src/Lib/V1/Contexts.ts | 381 +++++++++++++++++++++++++
src/Lib/V1/DCert.ts | 355 +++++++++++++++++++++++
src/Lib/V1/Tx.ts | 2 -
src/Tests/V1/DCertInstances-test.ts | 113 ++++++++
src/Tests/V1/TxInInfoInstances-test.ts | 75 +++++
src/Tests/V1/TxInfoInstances-test.ts | 95 ++++++
src/Tests/V1/TxOutRefInstances-test.ts | 2 +-
10 files changed, 1023 insertions(+), 7 deletions(-)
delete mode 100644 src/Lib/V1/Contexts.hs
create mode 100644 src/Lib/V1/Contexts.ts
create mode 100644 src/Lib/V1/DCert.ts
create mode 100644 src/Tests/V1/DCertInstances-test.ts
create mode 100644 src/Tests/V1/TxInInfoInstances-test.ts
create mode 100644 src/Tests/V1/TxInfoInstances-test.ts
diff --git a/src/Lib/AssocMap.ts b/src/Lib/AssocMap.ts
index f4acf2c..fc688e8 100644
--- a/src/Lib/AssocMap.ts
+++ b/src/Lib/AssocMap.ts
@@ -1,5 +1,5 @@
/**
- * TypeScript implementation for {@link *https://github.com/input-output-hk/plutus/blob/1.16.0.0/plutus-tx/src/PlutusTx/AssocMap.hs }
+ * TypeScript implementation for {@link https://github.com/input-output-hk/plutus/blob/1.16.0.0/plutus-tx/src/PlutusTx/AssocMap.hs }
*
* @example
* ```ts
diff --git a/src/Lib/V1.ts b/src/Lib/V1.ts
index 28477b6..9d85b13 100644
--- a/src/Lib/V1.ts
+++ b/src/Lib/V1.ts
@@ -19,4 +19,6 @@ export * from "./V1/Scripts.js";
export * from "./V1/Time.js";
export * from "./V1/Tx.js";
export * from "./V1/Value.js";
+export * from "./V1/DCert.js";
+export * from "./V1/Contexts.js";
export * from "./Prelude/Instances.js";
diff --git a/src/Lib/V1/Contexts.hs b/src/Lib/V1/Contexts.hs
deleted file mode 100644
index 0f14a12..0000000
--- a/src/Lib/V1/Contexts.hs
+++ /dev/null
@@ -1,3 +0,0 @@
-/**
- * @see {@link https://github.com/IntersectMBO/plutus/blob/1.16.0.0/plutus-ledger-api/src/PlutusLedgerApi/V1/Contexts.hs}
- */
diff --git a/src/Lib/V1/Contexts.ts b/src/Lib/V1/Contexts.ts
new file mode 100644
index 0000000..f318775
--- /dev/null
+++ b/src/Lib/V1/Contexts.ts
@@ -0,0 +1,381 @@
+/**
+ * @see {@link https://github.com/IntersectMBO/plutus/blob/1.16.0.0/plutus-ledger-api/src/PlutusLedgerApi/V1/Contexts.hs}
+ */
+
+import type { Eq, Integer, Json } from "prelude";
+import * as Prelude from "prelude";
+import * as PreludeInstances from "../Prelude/Instances.js";
+
+import type { TxId, TxOut, TxOutRef } from "./Tx.js";
+import * as LbTx from "./Tx.js";
+
+import type { Value } from "./Value.js";
+import * as LbValue from "./Value.js";
+
+import type { StakingCredential } from "./Credential.js";
+import * as LbCredential from "./Credential.js";
+
+import { IsPlutusDataError } from "../PlutusData.js";
+import type { IsPlutusData } from "../PlutusData.js";
+
+import type { DCert } from "./DCert.js";
+import * as LbDCert from "./DCert.js";
+
+import type { POSIXTimeRange } from "./Time.js";
+import * as LbTime from "./Time.js";
+
+import type { Datum, DatumHash } from "./Scripts.js";
+import * as LbScripts from "./Scripts.js";
+
+import * as LbCrypto from "./Crypto.js";
+import type { PubKeyHash } from "./Crypto.js";
+
+/**
+ * An input of a pending transaction.
+ * @see {@link https://github.com/IntersectMBO/plutus/blob/1.16.0.0/plutus-ledger-api/src/PlutusLedgerApi/V1/Contexts.hs#L66-L70}
+ */
+export type TxInInfo = {
+ txInInfoOutRef: TxOutRef;
+ txInInfoResolved: TxOut;
+};
+
+/**
+ * {@link Eq} instance for {@link TxInInfo}
+ */
+export const eqTxInInfo: Eq = {
+ eq: (l, r) => {
+ return LbTx.eqTxOutRef.eq(l.txInInfoOutRef, r.txInInfoOutRef) &&
+ LbTx.eqTxOut.eq(l.txInInfoResolved, r.txInInfoResolved);
+ },
+ neq: (l, r) => {
+ return LbTx.eqTxOutRef.neq(l.txInInfoOutRef, r.txInInfoOutRef) ||
+ LbTx.eqTxOut.neq(l.txInInfoResolved, r.txInInfoResolved);
+ },
+};
+
+/**
+ * {@link Json} instance for {@link TxInInfo}
+ */
+export const jsonTxInInfo: Json = {
+ toJson: (txInInfo) => {
+ return {
+ "output": LbTx.jsonTxOut.toJson(txInInfo.txInInfoResolved),
+ "reference": LbTx.jsonTxOutRef.toJson(txInInfo.txInInfoOutRef),
+ };
+ },
+ fromJson: (value) => {
+ const txInInfoOutRef = Prelude.caseFieldWithValue(
+ "reference",
+ LbTx.jsonTxOutRef.fromJson,
+ value,
+ );
+ const txInInfoResolved = Prelude.caseFieldWithValue(
+ "output",
+ LbTx.jsonTxOut.fromJson,
+ value,
+ );
+ return { txInInfoOutRef, txInInfoResolved };
+ },
+};
+
+/**
+ * {@link IsPlutusData} instance for {@link TxInInfo}
+ */
+export const isPlutusDataTxInInfo: IsPlutusData = {
+ toData: (txInInfo) => {
+ return {
+ fields: [0n, [
+ LbTx.isPlutusDataTxOutRef.toData(txInInfo.txInInfoOutRef),
+ LbTx.isPlutusDataTxOut.toData(txInInfo.txInInfoResolved),
+ ]],
+ name: "Constr",
+ };
+ },
+
+ fromData: (plutusData) => {
+ switch (plutusData.name) {
+ case "Constr": {
+ if (plutusData.fields[0] === 0n && plutusData.fields[1].length === 2) {
+ return {
+ txInInfoOutRef: LbTx.isPlutusDataTxOutRef.fromData(
+ plutusData.fields[1][0]!,
+ ),
+ txInInfoResolved: LbTx.isPlutusDataTxOut.fromData(
+ plutusData.fields[1][1]!,
+ ),
+ };
+ } else {
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ throw new IsPlutusDataError("Unexpected data");
+ },
+};
+
+/**
+ * A pending transaction. This is the view as seen by validator scripts, so
+ * some details are stripped out.
+ *
+ * @see {@link https://github.com/IntersectMBO/plutus/blob/1.16.0.0/plutus-ledger-api/src/PlutusLedgerApi/V1/Contexts.hs#L96-L108}
+ */
+export type TxInfo = {
+ txInfoInputs: TxInInfo[];
+ txInfoOutputs: TxOut[];
+ txInfoFee: Value;
+ txInfoMint: Value;
+ txInfoDCert: DCert[];
+ txInfoWdrl: [StakingCredential, Integer][];
+ txInfoValidRange: POSIXTimeRange;
+ txInfoSignatories: PubKeyHash[];
+ txInfoData: [DatumHash, Datum][];
+ txInfoId: TxId;
+};
+
+/**
+ * {@link Eq} instance for {@link TxInfo}
+ */
+export const eqTxInfo: Eq = {
+ eq: (l, r) => {
+ return Prelude.eqList(eqTxInInfo).eq(l.txInfoInputs, r.txInfoInputs) &&
+ Prelude.eqList(LbTx.eqTxOut).eq(l.txInfoOutputs, r.txInfoOutputs) &&
+ LbValue.eqValue.eq(l.txInfoFee, r.txInfoFee) &&
+ LbValue.eqValue.eq(l.txInfoMint, r.txInfoMint) &&
+ Prelude.eqList(LbDCert.eqDCert).eq(l.txInfoDCert, r.txInfoDCert) &&
+ Prelude.eqList(
+ Prelude.eqPair(LbCredential.eqStakingCredential, Prelude.eqInteger),
+ ).eq(l.txInfoWdrl, r.txInfoWdrl) &&
+ LbTime.eqPOSIXTimeRange.eq(l.txInfoValidRange, r.txInfoValidRange) &&
+ Prelude.eqList(LbCrypto.eqPubKeyHash).eq(
+ l.txInfoSignatories,
+ r.txInfoSignatories,
+ ) &&
+ Prelude.eqList(Prelude.eqPair(LbScripts.eqDatumHash, LbScripts.eqDatum))
+ .eq(l.txInfoData, r.txInfoData) &&
+ LbTx.eqTxId.eq(l.txInfoId, r.txInfoId);
+ },
+ neq: (l, r) => {
+ return Prelude.eqList(eqTxInInfo).neq(l.txInfoInputs, r.txInfoInputs) ||
+ Prelude.eqList(LbTx.eqTxOut).neq(l.txInfoOutputs, r.txInfoOutputs) ||
+ LbValue.eqValue.neq(l.txInfoFee, r.txInfoFee) ||
+ LbValue.eqValue.neq(l.txInfoMint, r.txInfoMint) ||
+ Prelude.eqList(LbDCert.eqDCert).neq(l.txInfoDCert, r.txInfoDCert) ||
+ Prelude.eqList(
+ Prelude.eqPair(LbCredential.eqStakingCredential, Prelude.eqInteger),
+ ).neq(l.txInfoWdrl, r.txInfoWdrl) ||
+ LbTime.eqPOSIXTimeRange.neq(l.txInfoValidRange, r.txInfoValidRange) ||
+ Prelude.eqList(LbCrypto.eqPubKeyHash).neq(
+ l.txInfoSignatories,
+ r.txInfoSignatories,
+ ) ||
+ Prelude.eqList(Prelude.eqPair(LbScripts.eqDatumHash, LbScripts.eqDatum))
+ .neq(l.txInfoData, r.txInfoData) ||
+ LbTx.eqTxId.neq(l.txInfoId, r.txInfoId);
+ },
+};
+
+/**
+ * {@link Json} instance for {@link TxInfo}
+ */
+export const jsonTxInfo: Json = {
+ toJson: (txInfo) => {
+ return {
+ inputs: Prelude.jsonList(jsonTxInInfo).toJson(txInfo.txInfoInputs),
+ outputs: Prelude.jsonList(LbTx.jsonTxOut).toJson(txInfo.txInfoOutputs),
+ fee: LbValue.jsonValue.toJson(txInfo.txInfoFee),
+ mint: LbValue.jsonValue.toJson(txInfo.txInfoMint),
+ d_cert: Prelude.jsonList(LbDCert.jsonDCert).toJson(txInfo.txInfoDCert),
+ wdrl: Prelude.jsonList(
+ Prelude.jsonPair(
+ LbCredential.jsonStakingCredential,
+ Prelude.jsonInteger,
+ ),
+ ).toJson(txInfo.txInfoWdrl),
+ valid_range: LbTime.jsonPOSIXTimeRange.toJson(txInfo.txInfoValidRange),
+ signatories: Prelude.jsonList(LbCrypto.jsonPubKeyHash).toJson(
+ txInfo.txInfoSignatories,
+ ),
+ datums: Prelude.jsonList(
+ Prelude.jsonPair(LbScripts.jsonDatumHash, LbScripts.jsonDatum),
+ ).toJson(txInfo.txInfoData),
+ id: LbTx.jsonTxId.toJson(txInfo.txInfoId),
+ };
+ },
+ fromJson: (value) => {
+ const txInfoInputs = Prelude.caseFieldWithValue(
+ "inputs",
+ Prelude.jsonList(jsonTxInInfo).fromJson,
+ value,
+ );
+ const txInfoOutputs = Prelude.caseFieldWithValue(
+ "outputs",
+ Prelude.jsonList(LbTx.jsonTxOut).fromJson,
+ value,
+ );
+ const txInfoFee = Prelude.caseFieldWithValue(
+ "fee",
+ LbValue.jsonValue.fromJson,
+ value,
+ );
+ const txInfoMint = Prelude.caseFieldWithValue(
+ "mint",
+ LbValue.jsonValue.fromJson,
+ value,
+ );
+ const txInfoDCert = Prelude.caseFieldWithValue(
+ "d_cert",
+ Prelude.jsonList(LbDCert.jsonDCert).fromJson,
+ value,
+ );
+ const txInfoWdrl = Prelude.caseFieldWithValue(
+ "wdrl",
+ Prelude.jsonList(
+ Prelude.jsonPair(
+ LbCredential.jsonStakingCredential,
+ Prelude.jsonInteger,
+ ),
+ ).fromJson,
+ value,
+ );
+ const txInfoValidRange = Prelude.caseFieldWithValue(
+ "valid_range",
+ LbTime.jsonPOSIXTimeRange.fromJson,
+ value,
+ );
+ const txInfoSignatories = Prelude.caseFieldWithValue(
+ "signatories",
+ Prelude.jsonList(LbCrypto.jsonPubKeyHash).fromJson,
+ value,
+ );
+ const txInfoData = Prelude.caseFieldWithValue(
+ "datums",
+ Prelude.jsonList(
+ Prelude.jsonPair(LbScripts.jsonDatumHash, LbScripts.jsonDatum),
+ ).fromJson,
+ value,
+ );
+ const txInfoId = Prelude.caseFieldWithValue(
+ "id",
+ LbTx.jsonTxId.fromJson,
+ value,
+ );
+
+ return {
+ txInfoInputs,
+ txInfoOutputs,
+ txInfoFee,
+ txInfoMint,
+ txInfoDCert,
+ txInfoWdrl,
+ txInfoValidRange,
+ txInfoSignatories,
+ txInfoData,
+ txInfoId,
+ };
+ },
+};
+
+/**
+ * {@link IsPlutusData} instance for {@link TxInfo}
+ */
+export const isPlutusDataTxInfo: IsPlutusData = {
+ toData: (txInfo) => {
+ return {
+ fields: [0n, [
+ PreludeInstances.isPlutusDataList(isPlutusDataTxInInfo).toData(
+ txInfo.txInfoInputs,
+ ),
+ PreludeInstances.isPlutusDataList(LbTx.isPlutusDataTxOut).toData(
+ txInfo.txInfoOutputs,
+ ),
+ LbValue.isPlutusDataValue.toData(txInfo.txInfoFee),
+ LbValue.isPlutusDataValue.toData(txInfo.txInfoMint),
+ PreludeInstances.isPlutusDataList(LbDCert.isPlutusDataDCert).toData(
+ txInfo.txInfoDCert,
+ ),
+ PreludeInstances.isPlutusDataList(
+ PreludeInstances.isPlutusDataPairWithTag(
+ LbCredential.isPlutusDataStakingCredential,
+ PreludeInstances.isPlutusDataInteger,
+ ),
+ ).toData(txInfo.txInfoWdrl),
+ LbTime.isPlutusDataPOSIXTimeRange.toData(txInfo.txInfoValidRange),
+ PreludeInstances.isPlutusDataList(LbCrypto.isPlutusDataPubKeyHash)
+ .toData(txInfo.txInfoSignatories),
+ PreludeInstances.isPlutusDataList(
+ PreludeInstances.isPlutusDataPairWithTag(
+ LbScripts.isPlutusDataDatumHash,
+ LbScripts.isPlutusDataDatum,
+ ),
+ ).toData(txInfo.txInfoData),
+ LbTx.isPlutusDataTxId.toData(txInfo.txInfoId),
+ ]],
+ name: "Constr",
+ };
+ },
+
+ fromData: (plutusData) => {
+ switch (plutusData.name) {
+ case "Constr": {
+ if (plutusData.fields[0] === 0n && plutusData.fields[1].length === 10) {
+ const txInfoInputs = PreludeInstances.isPlutusDataList(
+ isPlutusDataTxInInfo,
+ ).fromData(plutusData.fields[1][0]!);
+ const txInfoOutputs = PreludeInstances.isPlutusDataList(
+ LbTx.isPlutusDataTxOut,
+ ).fromData(plutusData.fields[1][1]!);
+ const txInfoFee = LbValue.isPlutusDataValue.fromData(
+ plutusData.fields[1][2]!,
+ );
+ const txInfoMint = LbValue.isPlutusDataValue.fromData(
+ plutusData.fields[1][3]!,
+ );
+ const txInfoDCert = PreludeInstances.isPlutusDataList(
+ LbDCert.isPlutusDataDCert,
+ ).fromData(plutusData.fields[1][4]!);
+ const txInfoWdrl = PreludeInstances.isPlutusDataList(
+ PreludeInstances.isPlutusDataPairWithTag(
+ LbCredential.isPlutusDataStakingCredential,
+ PreludeInstances.isPlutusDataInteger,
+ ),
+ ).fromData(plutusData.fields[1][5]!);
+ const txInfoValidRange = LbTime.isPlutusDataPOSIXTimeRange.fromData(
+ plutusData.fields[1][6]!,
+ );
+ const txInfoSignatories = PreludeInstances.isPlutusDataList(
+ LbCrypto.isPlutusDataPubKeyHash,
+ ).fromData(plutusData.fields[1][7]!);
+ const txInfoData = PreludeInstances.isPlutusDataList(
+ PreludeInstances.isPlutusDataPairWithTag(
+ LbScripts.isPlutusDataDatumHash,
+ LbScripts.isPlutusDataDatum,
+ ),
+ ).fromData(plutusData.fields[1][8]!);
+ const txInfoId = LbTx.isPlutusDataTxId.fromData(
+ plutusData.fields[1][9]!,
+ );
+
+ return {
+ txInfoInputs,
+ txInfoOutputs,
+ txInfoFee,
+ txInfoMint,
+ txInfoDCert,
+ txInfoWdrl,
+ txInfoValidRange,
+ txInfoSignatories,
+ txInfoData,
+ txInfoId,
+ };
+ } else {
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ throw new IsPlutusDataError("Unexpected data");
+ },
+};
diff --git a/src/Lib/V1/DCert.ts b/src/Lib/V1/DCert.ts
new file mode 100644
index 0000000..791e244
--- /dev/null
+++ b/src/Lib/V1/DCert.ts
@@ -0,0 +1,355 @@
+/**
+ * @see {@link https://github.com/IntersectMBO/plutus/blob/1.16.0.0/plutus-ledger-api/src/PlutusLedgerApi/V1/DCert.hs}
+ */
+
+import * as LbCredential from "./Credential.js";
+import type { StakingCredential } from "./Credential.js";
+import * as LbCrypto from "./Crypto.js";
+import type { PubKeyHash } from "./Crypto.js";
+import type { Eq, Integer, Json } from "prelude";
+import { JsonError } from "prelude";
+import { IsPlutusDataError } from "../PlutusData.js";
+import type { IsPlutusData } from "../PlutusData.js";
+import * as Prelude from "prelude";
+import * as PJson from "prelude/Json.js";
+import * as PreludeInstances from "../Prelude/Instances.js";
+
+/**
+ * {@link DCert} a representation of the ledger DCert.
+ *
+ * @see {@link https://github.com/IntersectMBO/plutus/blob/1.16.0.0/plutus-ledger-api/src/PlutusLedgerApi/V1/DCert.hs#L22-L46}
+ */
+export type DCert =
+ | { name: "DCertDelegRegKey"; fields: StakingCredential }
+ | { name: "DCertDelegDeRegKey"; fields: StakingCredential }
+ | { name: "DCertDelegDelegate"; fields: [StakingCredential, PubKeyHash] }
+ | { name: "DCertPoolRegister"; fields: [PubKeyHash, PubKeyHash] }
+ | { name: "DCertPoolRetire"; fields: [PubKeyHash, Integer] }
+ | { name: "DCertGenesis" }
+ | { name: "DCertMir" };
+
+/**
+ * {@link Eq} instance for {@link DCert}
+ */
+export const eqDCert: Eq = {
+ eq: (l, r) => {
+ if (l.name === "DCertDelegRegKey" && r.name === "DCertDelegRegKey") {
+ return LbCredential.eqStakingCredential.eq(l.fields, r.fields);
+ } else if (
+ l.name === "DCertDelegDeRegKey" && r.name === "DCertDelegDeRegKey"
+ ) {
+ return LbCredential.eqStakingCredential.eq(l.fields, r.fields);
+ } else if (
+ l.name === "DCertDelegDelegate" && r.name === "DCertDelegDelegate"
+ ) {
+ return LbCredential.eqStakingCredential.eq(l.fields[0], r.fields[0]) &&
+ LbCrypto.eqPubKeyHash.eq(l.fields[1], r.fields[1]);
+ } else if (
+ l.name === "DCertPoolRegister" && r.name === "DCertPoolRegister"
+ ) {
+ return LbCrypto.eqPubKeyHash.eq(l.fields[0], r.fields[0]) &&
+ LbCrypto.eqPubKeyHash.eq(l.fields[1], r.fields[1]);
+ } else if (l.name === "DCertPoolRetire" && r.name === "DCertPoolRetire") {
+ return LbCrypto.eqPubKeyHash.eq(l.fields[0], r.fields[0]) &&
+ Prelude.eqInteger.eq(l.fields[1], r.fields[1]);
+ } else if (l.name === "DCertGenesis" && r.name === "DCertGenesis") {
+ return true;
+ } else if (l.name === "DCertMir" && r.name === "DCertMir") {
+ return true;
+ } else {
+ return false;
+ }
+ },
+ neq: (l, r) => {
+ if (l.name === "DCertDelegRegKey" && r.name === "DCertDelegRegKey") {
+ return LbCredential.eqStakingCredential.neq(l.fields, r.fields);
+ } else if (
+ l.name === "DCertDelegDeRegKey" && r.name === "DCertDelegDeRegKey"
+ ) {
+ return LbCredential.eqStakingCredential.neq(l.fields, r.fields);
+ } else if (
+ l.name === "DCertDelegDelegate" && r.name === "DCertDelegDelegate"
+ ) {
+ return LbCredential.eqStakingCredential.neq(l.fields[0], r.fields[0]) ||
+ LbCrypto.eqPubKeyHash.neq(l.fields[1], r.fields[1]);
+ } else if (
+ l.name === "DCertPoolRegister" && r.name === "DCertPoolRegister"
+ ) {
+ return LbCrypto.eqPubKeyHash.neq(l.fields[0], r.fields[0]) ||
+ LbCrypto.eqPubKeyHash.neq(l.fields[1], r.fields[1]);
+ } else if (l.name === "DCertPoolRetire" && r.name === "DCertPoolRetire") {
+ return LbCrypto.eqPubKeyHash.neq(l.fields[0], r.fields[0]) ||
+ Prelude.eqInteger.neq(l.fields[1], r.fields[1]);
+ } else if (l.name === "DCertGenesis" && r.name === "DCertGenesis") {
+ return false;
+ } else if (l.name === "DCertMir" && r.name === "DCertMir") {
+ return false;
+ } else {
+ return true;
+ }
+ },
+};
+
+/**
+ * {@link Json} instance for {@link DCert}
+ */
+export const jsonDCert: Json = {
+ toJson: (dcert) => {
+ if (dcert.name === `DCertDelegRegKey`) {
+ return PJson.jsonConstructor(dcert.name, [
+ LbCredential.jsonStakingCredential.toJson(dcert.fields),
+ ]);
+ } else if (dcert.name === `DCertDelegDeRegKey`) {
+ return PJson.jsonConstructor(dcert.name, [
+ LbCredential.jsonStakingCredential.toJson(dcert.fields),
+ ]);
+ } else if (dcert.name === `DCertDelegDelegate`) {
+ return PJson.jsonConstructor(dcert.name, [
+ LbCredential.jsonStakingCredential.toJson(dcert.fields[0]),
+ LbCrypto.jsonPubKeyHash.toJson(dcert.fields[1]),
+ ]);
+ } else if (dcert.name === `DCertPoolRegister`) {
+ return PJson.jsonConstructor(dcert.name, [
+ LbCrypto.jsonPubKeyHash.toJson(dcert.fields[0]),
+ LbCrypto.jsonPubKeyHash.toJson(dcert.fields[1]),
+ ]);
+ } else if (dcert.name === `DCertPoolRetire`) {
+ return PJson.jsonConstructor(dcert.name, [
+ LbCrypto.jsonPubKeyHash.toJson(dcert.fields[0]),
+ Prelude.jsonInteger.toJson(dcert.fields[1]),
+ ]);
+ } else if (dcert.name === `DCertGenesis`) {
+ return PJson.jsonConstructor(dcert.name, []);
+ } else {
+ // else if (dcert.name === `DCertMir`) {
+ return PJson.jsonConstructor(dcert.name, []);
+ }
+ },
+ fromJson: (value) => {
+ return PJson.caseJsonConstructor("DCert", {
+ "DCertDelegRegKey": (ctorFields) => {
+ if (ctorFields.length === 1) {
+ return {
+ fields: LbCredential.jsonStakingCredential.fromJson(ctorFields[0]!),
+ name: "DCertDelegRegKey",
+ };
+ } else {
+ throw new JsonError(
+ "Expected JSON Array with 1 fields but got" +
+ PJson.stringify(value),
+ );
+ }
+ },
+ "DCertDelegDeRegKey": (ctorFields) => {
+ if (ctorFields.length === 1) {
+ return {
+ fields: LbCredential.jsonStakingCredential.fromJson(ctorFields[0]!),
+ name: "DCertDelegDeRegKey",
+ };
+ } else {
+ throw new JsonError(
+ "Expected JSON Array with 1 fields but got" +
+ PJson.stringify(value),
+ );
+ }
+ },
+ "DCertDelegDelegate": (ctorFields) => {
+ if (ctorFields.length === 2) {
+ return {
+ fields: [
+ LbCredential.jsonStakingCredential.fromJson(ctorFields[0]!),
+ LbCrypto.jsonPubKeyHash.fromJson(ctorFields[1]!),
+ ],
+ name: "DCertDelegDelegate",
+ };
+ } else {
+ throw new JsonError(
+ "Expected JSON Array with 1 fields but got" +
+ PJson.stringify(value),
+ );
+ }
+ },
+
+ "DCertPoolRegister": (ctorFields) => {
+ if (ctorFields.length === 2) {
+ return {
+ fields: [
+ LbCrypto.jsonPubKeyHash.fromJson(ctorFields[0]!),
+ LbCrypto.jsonPubKeyHash.fromJson(ctorFields[1]!),
+ ],
+ name: "DCertPoolRegister",
+ };
+ } else {
+ throw new JsonError(
+ "Expected JSON Array with 1 fields but got" +
+ PJson.stringify(value),
+ );
+ }
+ },
+
+ "DCertPoolRetire": (ctorFields) => {
+ if (ctorFields.length === 2) {
+ return {
+ fields: [
+ LbCrypto.jsonPubKeyHash.fromJson(ctorFields[0]!),
+ Prelude.jsonInteger.fromJson(ctorFields[1]!),
+ ],
+ name: "DCertPoolRetire",
+ };
+ } else {
+ throw new JsonError(
+ "Expected JSON Array with 1 fields but got" +
+ PJson.stringify(value),
+ );
+ }
+ },
+ "DCertGenesis": (ctorFields) => {
+ if (ctorFields.length === 0) {
+ return { name: "DCertGenesis" };
+ } else {
+ throw new JsonError(
+ "Expected JSON Array with 1 fields but got" +
+ PJson.stringify(value),
+ );
+ }
+ },
+ "DCertMir": (ctorFields) => {
+ if (ctorFields.length === 0) {
+ return { name: "DCertMir" };
+ } else {
+ throw new JsonError(
+ "Expected JSON Array with 1 fields but got" +
+ PJson.stringify(value),
+ );
+ }
+ },
+ }, value);
+ },
+};
+
+/**
+ * {@link IsPlutusData} instance for {@link DCert}
+ */
+export const isPlutusDataDCert: IsPlutusData = {
+ toData: (dcert) => {
+ if (dcert.name === `DCertDelegRegKey`) {
+ return {
+ fields: [0n, [
+ LbCredential.isPlutusDataStakingCredential.toData(dcert.fields),
+ ]],
+ name: "Constr",
+ };
+ } else if (dcert.name === `DCertDelegDeRegKey`) {
+ return {
+ fields: [1n, [
+ LbCredential.isPlutusDataStakingCredential.toData(dcert.fields),
+ ]],
+ name: "Constr",
+ };
+ } else if (dcert.name === `DCertDelegDelegate`) {
+ return {
+ fields: [2n, [
+ LbCredential.isPlutusDataStakingCredential.toData(dcert.fields[0]),
+ LbCrypto.isPlutusDataPubKeyHash.toData(dcert.fields[1]),
+ ]],
+ name: "Constr",
+ };
+ } else if (dcert.name === `DCertPoolRegister`) {
+ return {
+ fields: [3n, [
+ LbCrypto.isPlutusDataPubKeyHash.toData(dcert.fields[0]),
+ LbCrypto.isPlutusDataPubKeyHash.toData(dcert.fields[1]),
+ ]],
+ name: "Constr",
+ };
+ } else if (dcert.name === `DCertPoolRetire`) {
+ return {
+ fields: [4n, [
+ LbCrypto.isPlutusDataPubKeyHash.toData(dcert.fields[0]),
+ PreludeInstances.isPlutusDataInteger.toData(dcert.fields[1]),
+ ]],
+ name: "Constr",
+ };
+ } else if (dcert.name === `DCertGenesis`) {
+ return { fields: [5n, []], name: "Constr" };
+ } else {
+ // else if (dcert.name === `DCertMir`) {
+ return { fields: [6n, []], name: "Constr" };
+ }
+ },
+
+ fromData: (plutusData) => {
+ switch (plutusData.name) {
+ case "Constr":
+ if (plutusData.fields[0] === 0n && plutusData.fields[1].length === 1) {
+ return {
+ fields: LbCredential.isPlutusDataStakingCredential.fromData(
+ plutusData.fields[1][0]!,
+ ),
+ name: "DCertDelegRegKey",
+ };
+ } else if (
+ plutusData.fields[0] === 1n && plutusData.fields[1].length === 1
+ ) {
+ return {
+ fields: LbCredential.isPlutusDataStakingCredential.fromData(
+ plutusData.fields[1][0]!,
+ ),
+ name: "DCertDelegDeRegKey",
+ };
+ } else if (
+ plutusData.fields[0] === 2n && plutusData.fields[1].length === 2
+ ) {
+ return {
+ fields: [
+ LbCredential.isPlutusDataStakingCredential.fromData(
+ plutusData.fields[1][0]!,
+ ),
+ LbCrypto.isPlutusDataPubKeyHash.fromData(
+ plutusData.fields[1][1]!,
+ ),
+ ],
+ name: "DCertDelegDelegate",
+ };
+ } else if (
+ plutusData.fields[0] === 3n && plutusData.fields[1].length === 2
+ ) {
+ return {
+ fields: [
+ LbCrypto.isPlutusDataPubKeyHash.fromData(
+ plutusData.fields[1][0]!,
+ ),
+ LbCrypto.isPlutusDataPubKeyHash.fromData(
+ plutusData.fields[1][1]!,
+ ),
+ ],
+ name: "DCertPoolRegister",
+ };
+ } else if (
+ plutusData.fields[0] === 4n && plutusData.fields[1].length === 2
+ ) {
+ return {
+ fields: [
+ LbCrypto.isPlutusDataPubKeyHash.fromData(
+ plutusData.fields[1][0]!,
+ ),
+ PreludeInstances.isPlutusDataInteger.fromData(
+ plutusData.fields[1][1]!,
+ ),
+ ],
+ name: "DCertPoolRetire",
+ };
+ } else if (
+ plutusData.fields[0] === 5n && plutusData.fields[1].length === 0
+ ) {
+ return { name: "DCertGenesis" };
+ } else if (
+ plutusData.fields[0] === 6n && plutusData.fields[1].length === 0
+ ) {
+ return { name: "DCertMir" };
+ }
+ break;
+ }
+ throw new IsPlutusDataError("Expected Constr but got " + plutusData);
+ },
+};
diff --git a/src/Lib/V1/Tx.ts b/src/Lib/V1/Tx.ts
index f4815c7..8d2857e 100644
--- a/src/Lib/V1/Tx.ts
+++ b/src/Lib/V1/Tx.ts
@@ -166,8 +166,6 @@ export const isPlutusDataTxOutRef: IsPlutusData = {
},
};
-//////////////////////////////////////////////////
-
/**
* {@link TxOut} a transaction output consisting of a target address, a value,
* and optionally a datum hash.
diff --git a/src/Tests/V1/DCertInstances-test.ts b/src/Tests/V1/DCertInstances-test.ts
new file mode 100644
index 0000000..f1aedc2
--- /dev/null
+++ b/src/Tests/V1/DCertInstances-test.ts
@@ -0,0 +1,113 @@
+// Tests for the instances for `DCert`
+import * as V1 from "../../Lib/V1.js";
+import { describe, it } from "node:test";
+import * as TestUtils from "../TestUtils.js";
+import fc from "fast-check";
+
+import * as TestStakingCredential from "./StakingCredentialInstances-test.js";
+import * as TestPubKeyHash from "./PubKeyHashInstances-test.js";
+
+export function fcDCert(): fc.Arbitrary {
+ return fc.oneof(
+ fc.record(
+ {
+ name: fc.constant("DCertDelegRegKey"),
+ fields: TestStakingCredential.fcStakingCredential(),
+ },
+ ),
+ fc.record(
+ {
+ name: fc.constant("DCertDelegDeRegKey"),
+ fields: TestStakingCredential.fcStakingCredential(),
+ },
+ ),
+ fc.record(
+ {
+ name: fc.constant("DCertDelegDelegate"),
+ fields: fc.tuple(
+ TestStakingCredential.fcStakingCredential(),
+ TestPubKeyHash.fcPubKeyHash(),
+ ),
+ },
+ ),
+ fc.record(
+ {
+ name: fc.constant("DCertPoolRegister"),
+ fields: fc.tuple(
+ TestPubKeyHash.fcPubKeyHash(),
+ TestPubKeyHash.fcPubKeyHash(),
+ ),
+ },
+ ),
+ fc.record(
+ {
+ name: fc.constant("DCertPoolRetire"),
+ fields: fc.tuple(TestPubKeyHash.fcPubKeyHash(), fc.bigInt()),
+ },
+ ),
+ fc.record(
+ { name: fc.constant("DCertGenesis") },
+ ),
+ fc.record(
+ { name: fc.constant("DCertMir") },
+ ),
+ ) as fc.Arbitrary;
+}
+
+describe("DCert tests", () => {
+ describe("Eq Credential tests", () => {
+ const dict = V1.eqDCert;
+
+ // TODO(jaredponn): put some hard coded unit tests in
+
+ it(`eq is not neq property based tests`, () => {
+ fc.assert(
+ fc.property(
+ fcDCert(),
+ fcDCert(),
+ (l, r) => {
+ TestUtils.negationTest(dict, l, r);
+ },
+ ),
+ {
+ examples: [],
+ },
+ );
+ });
+ });
+
+ describe("Json DCert tests", () => {
+ it(`toJson/fromJson property based tests`, () => {
+ fc.assert(
+ fc.property(
+ fcDCert(),
+ (data) => {
+ TestUtils.toJsonFromJsonRoundTrip(V1.jsonDCert, data);
+ },
+ ),
+ {
+ examples: [],
+ },
+ );
+ });
+ });
+
+ describe("IsPlutusData DCert tests", () => {
+ it(`toData/fromData property based tests`, () => {
+ fc.assert(
+ fc.property(
+ fcDCert(),
+ (data) => {
+ TestUtils.isPlutusDataRoundTrip(
+ V1.isPlutusDataDCert,
+ data,
+ );
+ },
+ ),
+ {
+ examples: [],
+ },
+ );
+ });
+ });
+});
diff --git a/src/Tests/V1/TxInInfoInstances-test.ts b/src/Tests/V1/TxInInfoInstances-test.ts
new file mode 100644
index 0000000..e732c9d
--- /dev/null
+++ b/src/Tests/V1/TxInInfoInstances-test.ts
@@ -0,0 +1,75 @@
+// Tests for the instances for `DCert`
+import * as V1 from "../../Lib/V1.js";
+import { describe, it } from "node:test";
+import * as TestUtils from "../TestUtils.js";
+import fc from "fast-check";
+
+import * as TestTxOutRef from "./TxOutRefInstances-test.js";
+import * as TestTxOut from "./TxOutInstances-test.js";
+
+export function fcTxInInfo(): fc.Arbitrary {
+ return fc.record(
+ {
+ txInInfoOutRef: TestTxOutRef.fcTxOutRef(),
+ txInInfoResolved: TestTxOut.fcTxOut(),
+ },
+ ) as fc.Arbitrary;
+}
+
+describe("TxInInfo tests", () => {
+ describe("Eq TxInInfo tests", () => {
+ const dict = V1.eqTxInInfo;
+
+ // TODO(jaredponn): put some hard coded unit tests in
+
+ it(`eq is not neq property based tests`, () => {
+ fc.assert(
+ fc.property(
+ fcTxInInfo(),
+ fcTxInInfo(),
+ (l, r) => {
+ TestUtils.negationTest(dict, l, r);
+ },
+ ),
+ {
+ examples: [],
+ },
+ );
+ });
+ });
+
+ describe("Json TxInInfo tests", () => {
+ it(`toJson/fromJson property based tests`, () => {
+ fc.assert(
+ fc.property(
+ fcTxInInfo(),
+ (data) => {
+ TestUtils.toJsonFromJsonRoundTrip(V1.jsonTxInInfo, data);
+ },
+ ),
+ {
+ examples: [],
+ },
+ );
+ });
+ });
+
+ describe("IsPlutusData TxInInfo tests", () => {
+ it(`toData/fromData property based tests`, () => {
+ fc.assert(
+ fc.property(
+ fcTxInInfo(),
+ (data) => {
+ TestUtils.isPlutusDataRoundTrip(
+ V1.isPlutusDataTxInInfo,
+ data,
+ );
+ },
+ ),
+ {
+ examples: [],
+ },
+ );
+ });
+ });
+});
diff --git a/src/Tests/V1/TxInfoInstances-test.ts b/src/Tests/V1/TxInfoInstances-test.ts
new file mode 100644
index 0000000..4ac74de
--- /dev/null
+++ b/src/Tests/V1/TxInfoInstances-test.ts
@@ -0,0 +1,95 @@
+// Tests for the instances for `TxInfo`
+import * as V1 from "../../Lib/V1.js";
+import { describe, it } from "node:test";
+import * as TestUtils from "../TestUtils.js";
+import fc from "fast-check";
+
+import * as TestTxInInfo from "./TxInInfoInstances-test.js";
+import * as TestValue from "./ValueInstances-test.js";
+import * as TestDCert from "./DCertInstances-test.js";
+import * as TestStakingCredential from "./StakingCredentialInstances-test.js";
+import * as TestInterval from "./IntervalInstances-test.js";
+import * as TestPubKeyHash from "./PubKeyHashInstances-test.js";
+import * as TestDatumHash from "./DatumHashInstances-test.js";
+import * as TestDatum from "./DatumInstances-test.js";
+import * as TestTxId from "./TxIdInstances-test.js";
+import * as TestTxOut from "./TxOutInstances-test.js";
+
+export function fcTxInfo(): fc.Arbitrary {
+ return fc.record(
+ {
+ txInfoInputs: fc.array(TestTxInInfo.fcTxInInfo()),
+ txInfoOutputs: fc.array(TestTxOut.fcTxOut()),
+ txInfoFee: TestValue.fcValue(),
+ txInfoMint: TestValue.fcValue(),
+ txInfoDCert: fc.array(TestDCert.fcDCert()),
+ txInfoWdrl: fc.array(
+ fc.tuple(TestStakingCredential.fcStakingCredential(), fc.bigInt()),
+ ),
+ txInfoValidRange: TestInterval.fcInterval(fc.bigInt()),
+ txInfoSignatories: fc.array(TestPubKeyHash.fcPubKeyHash()),
+ txInfoData: fc.array(
+ fc.tuple(TestDatumHash.fcDatumHash(), TestDatum.fcDatum()),
+ ),
+ txInfoId: TestTxId.fcTxId(),
+ },
+ );
+}
+
+describe("TxInfo tests", () => {
+ describe("Eq TxInfo tests", () => {
+ const dict = V1.eqTxInfo;
+
+ // TODO(jaredponn): put some hard coded unit tests in
+
+ it(`eq is not neq property based tests`, () => {
+ fc.assert(
+ fc.property(
+ fcTxInfo(),
+ fcTxInfo(),
+ (l, r) => {
+ TestUtils.negationTest(dict, l, r);
+ },
+ ),
+ {
+ examples: [],
+ },
+ );
+ });
+ });
+
+ describe("Json TxInfo tests", () => {
+ it(`toJson/fromJson property based tests`, () => {
+ fc.assert(
+ fc.property(
+ fcTxInfo(),
+ (data) => {
+ TestUtils.toJsonFromJsonRoundTrip(V1.jsonTxInfo, data);
+ },
+ ),
+ {
+ examples: [],
+ },
+ );
+ });
+ });
+
+ describe("IsPlutusData TxInfo tests", () => {
+ it(`toData/fromData property based tests`, () => {
+ fc.assert(
+ fc.property(
+ fcTxInfo(),
+ (data) => {
+ TestUtils.isPlutusDataRoundTrip(
+ V1.isPlutusDataTxInfo,
+ data,
+ );
+ },
+ ),
+ {
+ examples: [],
+ },
+ );
+ });
+ });
+});
diff --git a/src/Tests/V1/TxOutRefInstances-test.ts b/src/Tests/V1/TxOutRefInstances-test.ts
index 0dc2572..9cafbe7 100644
--- a/src/Tests/V1/TxOutRefInstances-test.ts
+++ b/src/Tests/V1/TxOutRefInstances-test.ts
@@ -102,7 +102,7 @@ export function fcTxOutRef(): fc.Arbitrary {
}
describe("TxOutRef tests", () => {
- describe("Eq Credential tests", () => {
+ describe("Eq TxOutRef tests", () => {
const dict = V1.eqTxOutRef;
// Same address
From fe41ac7e5ec133bafa2bbbaee3a6a9084745a35d Mon Sep 17 00:00:00 2001
From: jared <>
Date: Thu, 29 Feb 2024 02:13:12 -0700
Subject: [PATCH 4/4] Fixed documentation typo
---
src/Lib/PlutusData.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Lib/PlutusData.ts b/src/Lib/PlutusData.ts
index 5e4d707..d6b4083 100644
--- a/src/Lib/PlutusData.ts
+++ b/src/Lib/PlutusData.ts
@@ -19,7 +19,7 @@ import * as LbHex from "./Hex.js";
/**
* {@link PlutusData} is a generic "data" type.
*
- * @see {@link https://github.com/input-output-hk/plutus/blob/1.16.0.0/plutus-core/plutus-core/src/PlutusCore/Data.hs#L33-L48 | `Data`}
+ * @see {@link https://github.com/input-output-hk/plutus/blob/1.16.0.0/plutus-core/plutus-core/src/PlutusCore/Data.hs#L33-L48 }
*/
export type PlutusData =
| { name: "Constr"; fields: [Integer, List] }