Skip to content

Commit

Permalink
Fix ContractId and TxId branded doc generation
Browse files Browse the repository at this point in the history
  • Loading branch information
hrajchert committed Feb 22, 2024
1 parent a0d24f3 commit d65c6a2
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 24 deletions.
20 changes: 12 additions & 8 deletions packages/adapter/src/io-ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,21 +150,25 @@ export interface BrandP<A, B extends A, I>
// This helper is a workaround to that issue, making sure that if the original codec
// has the same Output than the Actual type, the new codec outputs the branded type
// So a PositiveInt codec will have the type t.Type<PositiveInt, PositiveInt, unknown>
export function preservedBrand<A, I, B extends A>(
codec: t.Type<A, A, I>,
predicate: Refinement<A, B>,
name: string
): BrandP<A, B, I> {
export function preservedBrand<
C extends t.Any,
N extends string,
B extends { readonly [K in N]: symbol },
>(
codec: C,
predicate: Refinement<t.TypeOf<C>, t.Branded<t.TypeOf<C>, B>>,
name: N
): BrandP<t.TypeOf<C>, B, t.InputOf<C>> {
return new t.Type(
name,
(u): u is t.Branded<A, B> => codec.is(u) && predicate(u),
(u): u is t.Branded<t.TypeOf<C>, B> => codec.is(u) && predicate(u),
(u, c) =>
pipe(
codec.validate(u, c),
Either.chain((a) =>
predicate(a)
? t.success(a as t.Branded<A, B>)
: t.failure<t.Branded<A, B>>(
? t.success(a as t.Branded<t.TypeOf<C>, B>)
: t.failure<t.Branded<t.TypeOf<C>, B>>(
a,
c,
`Value does not satisfy the ${name} constraint`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
BlockHeader,
ContractIdGuard,
TextEnvelope,
TxIdGuard,
} from "@marlowe.io/runtime-core";
import { TxStatus } from "./status.js";
import { assertGuardEqual, proxy } from "@marlowe.io/adapter/io-ts";
Expand Down Expand Up @@ -97,7 +98,7 @@ export const TransactionDetailsGuard = assertGuardEqual(
proxy<TransactionDetails>(),
t.type({
contractId: ContractIdGuard,
transactionId: TxId,
transactionId: TxIdGuard,
continuations: optionFromNullable(G.BuiltinByteString),
tags: TagsGuard,
metadata: MetadataGuard,
Expand All @@ -108,7 +109,7 @@ export const TransactionDetailsGuard = assertGuardEqual(
outputUtxo: optionFromNullable(TxOutRef),
outputContract: optionFromNullable(G.Contract),
outputState: optionFromNullable(G.MarloweState),
consumingTx: optionFromNullable(TxId),
consumingTx: optionFromNullable(TxIdGuard),
invalidBefore: ISO8601,
invalidHereafter: ISO8601,
txBody: optionFromNullable(TextEnvelopeGuard),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
unTxOutRef,
ContractId,
ContractIdGuard,
TxIdGuard,
} from "@marlowe.io/runtime-core";
import { TxHeader, TxHeaderGuard } from "../header.js";
import { assertGuardEqual, proxy } from "@marlowe.io/adapter/io-ts";
Expand Down Expand Up @@ -125,7 +126,7 @@ export const GetTransactionsForContractResponseGuard = assertGuardEqual(
export type TransactionTextEnvelope = t.TypeOf<typeof TransactionTextEnvelope>;
export const TransactionTextEnvelope = t.type({
contractId: ContractIdGuard,
transactionId: TxId,
transactionId: TxIdGuard,
tx: TextEnvelopeGuard,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
HexTransactionWitnessSet,
HexTransactionWitnessSetGuard,
TxId,
TxIdGuard,
transactionWitnessSetTextEnvelope,
} from "@marlowe.io/runtime-core";

Expand Down Expand Up @@ -45,7 +46,7 @@ export const GetContractTransactionByIdRequestGuard = assertGuardEqual(
proxy<GetContractTransactionByIdRequest>(),
t.type({
contractId: ContractIdGuard,
txId: TxId,
txId: TxIdGuard,
})
);

Expand Down Expand Up @@ -80,7 +81,7 @@ export const SubmitContractTransactionRequestGuard = assertGuardEqual(
proxy<SubmitContractTransactionRequest>(),
t.type({
contractId: ContractIdGuard,
transactionId: TxId,
transactionId: TxIdGuard,
hexTransactionWitnessSet: HexTransactionWitnessSetGuard,
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
TxOutRef,
TxId,
ContractId,
TxIdGuard,
} from "@marlowe.io/runtime-core";
import { TxStatus } from "./status.js";
import { BuiltinByteString } from "@marlowe.io/language-core-v1";
Expand Down Expand Up @@ -46,7 +47,7 @@ export interface TxHeader {
*/
export const TxHeaderGuard = t.type({
contractId: ContractIdGuard,
transactionId: TxId,
transactionId: TxIdGuard,
continuations: optionFromNullable(G.BuiltinByteString),
tags: TagsGuard,
metadata: MetadataGuard,
Expand Down
12 changes: 9 additions & 3 deletions packages/runtime/core/src/contract/id.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as t from "io-ts/lib/index.js";
import { split } from "fp-ts/lib/string.js";
import { pipe } from "fp-ts/lib/function.js";
import { head } from "fp-ts/lib/ReadonlyNonEmptyArray.js";
import { TxId } from "../tx/id.js";
import { TxId, txId } from "../tx/id.js";
import { unsafeEither } from "@marlowe.io/adapter/fp-ts";
import { preservedBrand } from "@marlowe.io/adapter/io-ts";

Expand All @@ -16,11 +16,17 @@ export const ContractIdGuard = preservedBrand(
"ContractId"
);

export type ContractId = t.TypeOf<typeof ContractIdGuard>;
/**
* Marlowe contract identifier.
*
* @remarks The underlying data structure is a normal string, but in the type
* level it is **Branded** with a unique symbol so that it is not confused with other strings
*/
export type ContractId = t.Branded<string, ContractIdBrand>;

export const contractId = (s: string) =>
unsafeEither(ContractIdGuard.decode(s));

export const contractIdToTxId: (contractId: ContractId) => TxId = (
contractId
) => pipe(contractId, split("#"), head);
) => pipe(contractId, split("#"), head, txId);
6 changes: 3 additions & 3 deletions packages/runtime/core/src/payout/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { fromNewtype } from "io-ts-types";
import { split } from "fp-ts/lib/string.js";
import { pipe } from "fp-ts/lib/function.js";
import { head } from "fp-ts/lib/ReadonlyNonEmptyArray.js";
import { TxId } from "../tx/id.js";
import { txId, TxId } from "../tx/id.js";
import { ContractIdGuard } from "../contract/id.js";
import { AssetId, Assets } from "../asset/index.js";

Expand All @@ -15,7 +15,7 @@ export const unPayoutId = iso<PayoutId>().unwrap;
export const payoutId = iso<PayoutId>().wrap;

export const payoutIdToTxId: (payoutId: PayoutId) => TxId = (payoutId) =>
pipe(payoutId, unPayoutId, split("#"), head);
pipe(payoutId, unPayoutId, split("#"), head, txId);

export type WithdrawalId = Newtype<
{ readonly WithdrawalId: unique symbol },
Expand All @@ -27,7 +27,7 @@ export const withdrawalId = iso<WithdrawalId>().wrap;

export const withdrawalIdToTxId: (withdrawalId: WithdrawalId) => TxId = (
withdrawalId
) => pipe(withdrawalId, unWithdrawalId);
) => pipe(withdrawalId, unWithdrawalId, txId);

// DISCUSSION: PayoutAvailable or AvailablePayout?
export type PayoutAvailable = t.TypeOf<typeof PayoutAvailable>;
Expand Down
24 changes: 20 additions & 4 deletions packages/runtime/core/src/tx/id.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
import { unsafeEither } from "@marlowe.io/adapter/fp-ts";
import * as t from "io-ts/lib/index.js";

// TODO: Try to make newtype as this gets replaced to string
// in the docs.
export type TxId = t.TypeOf<typeof TxId>;
export const TxId = t.string; // to refine
export interface TxIdBrand {
readonly TxId: unique symbol;
}

/**
* Cardano transaction identifier.
*
* @remarks The underlying data structure is a normal string, but in the type
* level it is **Branded** with a unique symbol so that it is not confused with other strings
*/
export type TxId = t.Branded<string, TxIdBrand>;

export const TxIdGuard = t.brand(
t.string,
(s): s is t.Branded<string, TxIdBrand> => true,
"TxId"
);

export const txId = (s: string) => unsafeEither(TxIdGuard.decode(s));
3 changes: 3 additions & 0 deletions typedoc.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
"fp-ts": {
"Option": "https://gcanti.github.io/fp-ts/modules/Option.ts.html"
},
"io-ts": {
"Branded": "https://github.com/gcanti/io-ts/blob/master/index.md#branded-types--refinements"
},
"lucid-cardano": {
"Lucid": "https://deno.land/x/lucid@0.10.7/mod.ts?s=Lucid"
},
Expand Down

0 comments on commit d65c6a2

Please sign in to comment.