@helios-lang/effect 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/Ledger/Address.js +156 -0
  2. package/dist/Ledger/Address.js.map +1 -0
  3. package/dist/Ledger/AssetClass.js +74 -0
  4. package/dist/Ledger/AssetClass.js.map +1 -0
  5. package/dist/Ledger/Assets.js +122 -0
  6. package/dist/Ledger/Assets.js.map +1 -0
  7. package/dist/Ledger/Credential.js +17 -0
  8. package/dist/Ledger/Credential.js.map +1 -0
  9. package/dist/Ledger/DatumHash.js +21 -0
  10. package/dist/Ledger/DatumHash.js.map +1 -0
  11. package/dist/Ledger/MintingPolicy.js +45 -0
  12. package/dist/Ledger/MintingPolicy.js.map +1 -0
  13. package/dist/Ledger/PubKeyHash.js +21 -0
  14. package/dist/Ledger/PubKeyHash.js.map +1 -0
  15. package/dist/Ledger/TxId.js +15 -0
  16. package/dist/Ledger/TxId.js.map +1 -0
  17. package/dist/Ledger/TxInput.js +51 -0
  18. package/dist/Ledger/TxInput.js.map +1 -0
  19. package/dist/Ledger/TxOutput.js +118 -0
  20. package/dist/Ledger/TxOutput.js.map +1 -0
  21. package/dist/Ledger/TxOutputDatum.js +41 -0
  22. package/dist/Ledger/TxOutputDatum.js.map +1 -0
  23. package/dist/Ledger/TxOutputId.js +39 -0
  24. package/dist/Ledger/TxOutputId.js.map +1 -0
  25. package/dist/Ledger/ValidatorHash.js +21 -0
  26. package/dist/Ledger/ValidatorHash.js.map +1 -0
  27. package/dist/Ledger/index.js +14 -0
  28. package/dist/Ledger/index.js.map +1 -0
  29. package/dist/Uplc/Data.js +229 -21
  30. package/dist/Uplc/Data.js.map +1 -1
  31. package/dist/Uplc/index.js +0 -1
  32. package/dist/Uplc/index.js.map +1 -1
  33. package/dist/index.js +1 -1
  34. package/dist/index.js.map +1 -1
  35. package/package.json +14 -10
  36. package/src/Ledger/Address.ts +252 -0
  37. package/src/Ledger/AssetClass.ts +96 -0
  38. package/src/Ledger/Assets.ts +164 -0
  39. package/src/Ledger/Credential.ts +29 -0
  40. package/src/Ledger/DatumHash.ts +36 -0
  41. package/src/Ledger/MintingPolicy.ts +57 -0
  42. package/src/Ledger/PubKeyHash.ts +36 -0
  43. package/src/Ledger/TxId.ts +31 -0
  44. package/src/Ledger/TxInput.test.ts +21 -0
  45. package/src/Ledger/TxInput.ts +66 -0
  46. package/src/Ledger/TxOutput.ts +165 -0
  47. package/src/Ledger/TxOutputDatum.ts +64 -0
  48. package/src/Ledger/TxOutputId.ts +63 -0
  49. package/src/Ledger/ValidatorHash.ts +36 -0
  50. package/src/Ledger/index.ts +13 -0
  51. package/src/Uplc/Data.test.ts +321 -0
  52. package/src/Uplc/Data.ts +445 -47
  53. package/src/Uplc/index.ts +0 -1
  54. package/src/index.ts +1 -1
  55. package/src/Address.ts +0 -20
  56. package/src/Uplc/DataSchema.test.ts +0 -207
  57. package/src/Uplc/DataSchema.ts +0 -181
@@ -0,0 +1,36 @@
1
+ import { Effect, Encoding, Schema } from "effect"
2
+ import * as Bytes from "../internal/Bytes.js"
3
+ import { decodeBytes, DecodeEffect, encodeBytes } from "../Cbor.js"
4
+ import { Data } from "../Uplc"
5
+
6
+ export function isValid(pkh: string): pkh is PubKeyHash {
7
+ return /^[0-9a-fA-F]+$/.test(pkh) && pkh.length == 56
8
+ }
9
+
10
+ export const PubKeyHash = Schema.String.pipe(
11
+ Schema.filter((pkh: string) => isValid(pkh) || "Invalid Cardano PubKeyHash"),
12
+ Schema.brand("PubKeyHash")
13
+ )
14
+
15
+ export type PubKeyHash = Schema.Schema.Type<typeof PubKeyHash>
16
+
17
+ export function make(bytes: Bytes.BytesLike) {
18
+ return Schema.decode(PubKeyHash)(Bytes.toHex(bytes))
19
+ }
20
+
21
+ export const FromUplcData = Schema.transform(Data.ByteArray, PubKeyHash, {
22
+ strict: true,
23
+ decode: Encoding.encodeHex,
24
+ encode: (s) => Effect.runSync(Encoding.decodeHex(s))
25
+ })
26
+
27
+ export const decode = (bytes: Bytes.BytesLike): DecodeEffect<PubKeyHash> =>
28
+ decodeBytes(bytes).pipe(
29
+ Effect.map((bytes) => new Uint8Array(bytes)),
30
+ Effect.map(Encoding.encodeHex),
31
+ Effect.map(Schema.decodeSync(PubKeyHash))
32
+ )
33
+
34
+ export function encode(pkh: PubKeyHash): number[] {
35
+ return encodeBytes(pkh)
36
+ }
@@ -0,0 +1,31 @@
1
+ import { Effect, Schema } from "effect"
2
+ import * as Bytes from "../internal/Bytes.js"
3
+ import * as Cbor from "../Cbor.js"
4
+
5
+ export function isValid(txId: string): txId is TxId {
6
+ return txId.length == 64 && /^[0-9a-fA-F]+$/.test(txId)
7
+ }
8
+
9
+ export const TxId = Schema.String.pipe(
10
+ Schema.filter((id: string) => isValid(id) || "Invalid Cardano TxId"),
11
+ Schema.brand("TxId")
12
+ )
13
+
14
+ export type TxId = Schema.Schema.Type<typeof TxId>
15
+
16
+ export function make(txId: Bytes.BytesLike) {
17
+ return Schema.decode(TxId)(Bytes.toHex(txId))
18
+ }
19
+
20
+ export const decode = (bytes: Bytes.BytesLike): Cbor.DecodeEffect<TxId> =>
21
+ Cbor.decodeBytes(bytes).pipe(
22
+ Effect.flatMap(make),
23
+ Effect.catchTag(
24
+ "ParseError",
25
+ (e) => new Cbor.DecodeError(Bytes.makeStream(bytes), e.message)
26
+ )
27
+ )
28
+
29
+ export function encode(txId: TxId): number[] {
30
+ return Cbor.encodeBytes(txId)
31
+ }
@@ -0,0 +1,21 @@
1
+ import { describe, it } from "bun:test"
2
+ import { Effect } from "effect"
3
+ import { decode } from "./TxInput.js"
4
+
5
+ describe("TxInput.decode()", () => {
6
+ it("works for UTxO returned from Cip30 wallet", () => {
7
+ Effect.runSync(
8
+ decode(
9
+ "828258204cb4e9f79554fb3b572b19f68c8cce0dba929fcee2f6ab6cc390419a8d703bd8181882581d604988cad9aa1ebd733b165695cfef965fda2ee42dab2d8584c43b039c1a49da0141"
10
+ )
11
+ )
12
+ })
13
+
14
+ it("works for UTXO with V3 ref script", () => {
15
+ Effect.runSync(
16
+ decode(
17
+ "828258203d308c0f3deb1eff764cbb765452c53d30704748681d7acd61c7775aeb8a8e4600a4011a01393d92028201d8185853d8799f581c3babcffc6102ec25ced40e1a24fba20371925c46f0299b2b9456360ed8799f581cdb0d968cda2cc636b28c0f377e66691a065b8004e57be5129aeef8224461757468ff1a000f42401832183205ff03d818591174820259116f59116c010100333333323232323232323223222322322322322533300d3232323232533233013300130143754004264664464646464a66603460060022a66603a60386ea80280085854ccc068c02000454ccc074c070dd50050010b0a99980d18020008a99980e980e1baa00a0021616301a37540122646464646464646464a666042601460446ea80304c8c8c8c8c8c8c8c94ccc0a4c048c0a8dd50008991919191919191919191929919981a980f00409919299981d181e80109919191919299981e1813181e9baa001132533303d302b303e375400826601600226464646464a66608a60900042646464646464a666090606c60926ea8c134c138c128dd518268030a999824181918249baa00213253330493037304a37540042a666092606460946ea80044c8c8c8c8c8c8c8c8c8c94ccc158c1640084c8c8c8c8c8c8c8c8c8c8c8c8c94ccc18008454ccc18008c54ccc18000c54ccc18000840045280a5014a02940cdd79ba6041374c666605c666605c666062076022900101d807a40040ba9101044655454c0005432533333306600114a02646464a646660cc0042a6660c6600200a266e25200000314a026644a6660ca66ebcc19800930101400015333065337126eb4c19cc1a8dd59833801002898019ba600114a02a6660ca66e2520000051300300714a060d000460d20046ebcc19cc1a000cdd5801992999830982518311baa0011375a60c660cc6eacc198c18cdd50008a400060ca0026466600200203844660cc004660cc6e980052f5c0444a6660ca00426600298103d87a80004bd6f7b630099199911299983319b9148900003153330663371e91010000313300530403306a374c00497ae00011330054c103d87a8000006133300700700122330070023306c337606ea4014dd30020009bae3064001375660ca00260d200660ce00429405280a50374c666605a666060074020900102e245044655454c00053533305d337120a86466e00c004050c00404894ccc178cdc4000a40002605400220022a6660ba0062a6660ba004200229405280a5032533305d304b305e3754002266e24dd69831182f9baa00100b163037305e3754606060bc6ea80f4cdc780599b8a48810550494c4f54003730600407066e3c030cdc52450453484950003730600206e46e64cc008dd4000a450030010012225333233330620031323232323300a0013371491101280053330620021337149101035b5d2900006133714911035b5f2000333300900233714911025d29000062233300a00a00230070012233300a00a002001533305e337100049007099b80483c80400854ccc178cdc40012410004266e00cdc0241002800490068b1bac305f002375a60ba0026466ec0dd4182e8009ba7305e0013754006264a6660be002266e292201027b7d00003133714911037b5f20003232330010010032253330620011003132533306300113233300a00a3062001337149101023a200033300a00a3063001005306500213233300a00a3062001337149101023a200033300a00a30630013007330040040023065002306500133714910102207d000033756006264a6660be002266e29221025b5d00003133714911035b5f2000333300600133714911015d000032233300700700230040012233300700700200137580066e292201022c2000133005375a00400226466e2922010268270032333001001337006e340092001337149101012700003222533305e3371000490000800899191919980300319b8000548004cdc599b80002533306133710004900a0a40c02903719b8b33700002a6660c266e2000520141481805206e0043370c004901019b8300148080cdc70020011bae0022222323300100100522533305f00110051325333060001133004306200200613300530620023300300300130620012232330010010032253330593042001133714910101300000315333059337100029000099b8a489012d0033002002302500113300533708002900a19b8b3370066e1400520144818000cc0040048894ccc158cdc4801240002002266600600666e1000920143371666e00cdc28012402890300008b1bad30570013057002375c60aa00260aa0046eb8c14c004c14c008dd6982880098288011bad304f001304b37540022c2c609a60946ea80085858c130c134008c12c004c12c008dd59824800982480098221baa0011630460013300d0232325333042303030433754002266e3c078dd7182398221baa00114a0603860866ea8c070c10cdd5000a99981f99baf374c00a6e98cccc038dd5980998209baa30133041375402c9110048810003a100114a066e212000333013004375c603260806ea80ecdd7180918201baa03b3375e602e660826ea0cdc000d24004660826ea40652f5c00022c6082607c6ea800458c10000cdd5981f801981f181f800981f000981e981c9baa00116303b0013300201823375e602260706ea8004c044c0e0dd51805181c1baa00d15333035302300813232533303a303d00213232323232533303c3026303d3754002264a66607a6056607c6ea80104c8c8c8c8c94ccc114c1200084c8c8c8c8c94ccc11cc0c4c120dd50008992999824181b18249baa00413232533304a3033304b3754006264646464646464646464a6660ae60b40042646464a6660ae0342a6660ae0322a6660ae0302a6660ae01e2a6660ae01c2a6660ae0062a6660ae004200229405280a5014a029405280a503375e6e980e0dd31999812999814019003a40020a89101044655454c00302233302b0110544881044655454c00325333056304430573754002266e2400cdd6982d982c1baa00116303030573754606060ae6ea80d8cdd79ba7330583750012660b06ea001d2f5c0981049f0000ff0016375a60b000260b00046eb8c158004c158008dd7182a000982a0011bad30520013052002375a60a000260986ea800c58cdd79ba732323300100102b22533304f00114bd70099199911299982819baf00700313305400233006006001133006006001304e001304f001305300230510013374a900119826981218259baa0084bd701ba73304d4c0103d87b80004bd70191929998269828001099299982599b88371a00400229404cdc7999b8c480000040092201045348495000371a910104534849500016375c609c002646600200264a666094607060966ea800452f5bded8c026eacc13cc130dd50009980f8020129129998268008a5eb804cc138c12cc13c004cc008008c14000458c130c124dd50008b18258019bab304a0033049304a0013049001304830443754602c60886ea800458c118004cc0340908c8c8c94ccc110c0c8c114dd50008a999822181918229baa3049304a00213371e6eb8c124c118dd5000810001801982400098221baa301d30443754602c60886ea80085281919baf374c600200c6e98c004dd5980a18211baa30143042375402e4646600200200444a66608a002297adef6c60132333222533304633722910100003153330463371e9101000031001100513304a337606ea400cdd3001198030030009bae30440013756608a0026092004608e00264646464a666084605660866ea80044c8c8c8cdc499b82375a60940026eb4c128c12c008cdc11bad304a002375a60946096002608c6ea8c8c8c080cc128dd419b82375a60960046eb4c12c004cc128dd419b82375a609660980046eb4c12cc1300052f5c0608e6ea8c8c8c8c8c08ccc134dd419b81337046eb4c138010004cdc11bad304e0020033304d375066e0800c0052f5c06eb4c134c138004c124dd5182618249baa006375a60966098002608e6ea8c00d200230463754600400a608a6ea8c00400c8c074cc11cdd400099823a610101004bd700b2999820a5014c0103d87a8000153330414a0260366608a60366608a6ea0c0340e8cc1153001023863004bd7025eb804c06ccc114c06ccc114dd401d19822a61021864004bd7025eb80c008018c004dd5980998209baa30133041375402c46660280029101004881003300b00113375e0380022c6082607c6ea800458c10000cdd5981f801981f181f800981f000981e981c9baa00116303b0013300201823375e602260706ea8004c044c0e0dd51805181c1baa00d15333035301e303637546601c0324a66606c66606ca66606c603e606e6ea8c044c0e0dd51808981c1baa300a303837540022940528a504a2266e21200033300b3756601460706ea8c028c0e0dd50009bae3011303837540666eb8c028c0e0dd50198a5014a22940dc0a400044646600200200644a666074002297ae0133225333039300500213303d00233004004001133004004001303c001303d001225333034301d30353754004264646464a666076607c00400a2c6eb8c0f0004c0f0008dd6981d000981b1baa0021622225333035301e0011004132323300100100622533303b00113303c337606ea4018dd3001a5eb7bdb1804c8ccc8894ccc0f0cdc800500189982019bb037520146e9801c01454ccc0f0cdc7805001899299981e9813181f1baa001133041337606ea402cc108c0fcdd5000801080119299981ea9998200008a5114a02980103d87a80001301733041374c00297ae03233001001003225333041001133042337606ea402cdd400525eb7bdb1804c8ccc8894ccc108cdc800780189982319bb0375201e6ea003801454ccc108cdc78078018992999821981618221baa001133047337606ea4040c120c114dd5000801080119299982198160008a6103d87a80001301d33047375000297ae03370000401c26608c66ec0dd48019ba800233006006001375c60800026eb4c104004c114008c10c0044cc100cdd81ba9003374c0046600c00c0026eb8c0e8004dd5981d800981f801181e800991900118030009981c99bb037520046ea00052f5bded8c0600200244a666068002293099299981a8008a4c264666444a66606c66e4000c0084cc01c01ccc0e801000458dd7181a181c0019bae30340013039002303700130370012225333031301a00114bd6f7b6300991919800800a5eb7bdb180894ccc0dc0044cc0e0cdd81ba9006374c00697adef6c6013233322253330383372001400626607866ec0dd48051ba6007005153330383371e01400626607866ec0dd48051ba600700113303c337606ea400cdd3001198030030009bae30360013756606e00260760046072002646600200297adef6c60225333036001133037337606ea4010dd4001a5eb7bdb1804c8ccc8894ccc0dccdc800400189981d99bb037520106ea001c01454ccc0dccdc780400189981d99bb037520106ea001c0044cc0eccdd81ba900337500046600c00c0026eb8c0d4004dd6981b000981d001181c00098171baa01d23032303300122232533302f301d303037540022900009bad30343031375400264a66605e603a60606ea80045300103d87a8000132330010013756606a60646ea8008894ccc0d0004530103d87a80001323332225333035337220100062a66606a66e3c02000c4c03ccc0e4dd400125eb80530103d87a8000133006006001375c60660026eb4c0d0004c0e0008c0d8004cc01000c00888c8cc00400400c894ccc0c4004530103d87a800013233322253330323372200e0062a66606466e3c01c00c4c030cc0d8dd300125eb80530103d87a8000133006006001375c60600026eacc0c4004c0d4008c0cc004c0b8c0acdd50008b19800806119baf3004302b375400202a44646600200200644a66605c0022980103d87a800013322533302d300500213007330310024bd70099802002000981800098188009ba5480008c0ac004dd7181498150011bad302800130243754002604c60466ea803058dd598129813181300298120021bab3023004375860440086eb0c084010c084c084c084004c080c080004c07cc07c004c068dd50049b8748000dc3a4008603200260326034002602a6ea8008dc3a40042c602c602e006602a00460280046028002601e6ea800452613656375a0026eb4004dd68009bad001375c002ae6955ceaab9e5573eae815d0aba2574898011e581c3babcffc6102ec25ced40e1a24fba20371925c46f0299b2b9456360e004c0127d8799f581cdb0d968cda2cc636b28c0f377e66691a065b8004e57be5129aeef8224461757468ff004c01051a000f4240004c01021832004c01021832004c010105000100581d7177799e0f07f377c76676fe9232b9b0bc57ca92c56132817c1ba06d0b"
18
+ )
19
+ )
20
+ })
21
+ })
@@ -0,0 +1,66 @@
1
+ import { Effect, Schema } from "effect"
2
+ import * as Bytes from "../internal/Bytes.js"
3
+ import * as Cbor from "../Cbor.js"
4
+ import * as TxOutput from "./TxOutput.js"
5
+ import * as TxOutputId from "./TxOutputId.js"
6
+
7
+ export const TxInput = Schema.TaggedStruct("TxInput", {
8
+ id: TxOutputId.TxOutputId,
9
+ output: Schema.optional(TxOutput.TxOutput)
10
+ })
11
+
12
+ export type TxInput = Schema.Schema.Type<typeof TxInput>
13
+
14
+ export function make(
15
+ id: TxOutputId.TxOutputId,
16
+ output: TxOutput.TxOutput | undefined = undefined
17
+ ): TxInput {
18
+ return {
19
+ _tag: "TxInput",
20
+ id,
21
+ output
22
+ }
23
+ }
24
+
25
+ export const decode = (bytes: Bytes.BytesLike): Cbor.DecodeEffect<TxInput> =>
26
+ Effect.gen(function* () {
27
+ const stream = Bytes.makeStream(bytes)
28
+
29
+ if (yield* (yield* Cbor.decodeTupleLazy(stream.copy()))(Cbor.isBytes)) {
30
+ const id = yield* TxOutputId.decode(stream)
31
+
32
+ return make(id)
33
+ } else if (
34
+ yield* (yield* Cbor.decodeTupleLazy(stream.copy()))(Cbor.isTuple)
35
+ ) {
36
+ const [id, output] = yield* Cbor.decodeTuple([
37
+ TxOutputId.decode,
38
+ TxOutput.decode
39
+ ])(stream)
40
+
41
+ return make(id, output)
42
+ } else {
43
+ return yield* Effect.fail(
44
+ new Cbor.DecodeError(stream, "unhandled TxInput encoding")
45
+ )
46
+ }
47
+ })
48
+
49
+ export function encode(txInput: TxInput, full: boolean = false) {
50
+ if (full) {
51
+ return Cbor.encodeTuple([
52
+ TxOutputId.encode(txInput.id),
53
+ TxOutput.encode(output(txInput))
54
+ ])
55
+ } else {
56
+ return TxOutputId.encode(txInput.id)
57
+ }
58
+ }
59
+
60
+ export function output(txInput: TxInput): TxOutput.TxOutput {
61
+ if (!txInput.output) {
62
+ throw new Error("txInput.output not available")
63
+ }
64
+
65
+ return txInput.output
66
+ }
@@ -0,0 +1,165 @@
1
+ import { Effect, Schema } from "effect"
2
+ import * as Bytes from "../internal/Bytes.js"
3
+ import * as Cbor from "../Cbor.js"
4
+ import * as Address from "./Address.js"
5
+ import * as Assets from "./Assets.js"
6
+ import * as DatumHash from "./DatumHash.js"
7
+ import * as TxOutputDatum from "./TxOutputDatum.js"
8
+
9
+ export const TxOutputEncodingConfig = Schema.Struct({
10
+ strictBabbage: Schema.optional(Schema.Boolean)
11
+ })
12
+
13
+ export type TxOutputEncodingConfig = Schema.Schema.Type<
14
+ typeof TxOutputEncodingConfig
15
+ >
16
+
17
+ export const DEFAULT_TX_OUTPUT_ENCODING_CONFIG: TxOutputEncodingConfig = {
18
+ strictBabbage: true
19
+ }
20
+
21
+ // TODO: add ref script
22
+ export const TxOutput = Schema.TaggedStruct("TxOutput", {
23
+ address: Address.Address,
24
+ assets: Assets.Assets,
25
+ datum: Schema.optional(TxOutputDatum.TxOutputDatum),
26
+ refScript: Schema.optional(Schema.Uint8ArrayFromSelf),
27
+ encodingConfig: Schema.Struct({
28
+ strictBabbage: Schema.optional(Schema.Boolean)
29
+ })
30
+ })
31
+
32
+ export type TxOutput = Schema.Schema.Type<typeof TxOutput>
33
+
34
+ export function make({
35
+ address,
36
+ assets,
37
+ datum = undefined,
38
+ refScript = undefined,
39
+ encodingConfig = DEFAULT_TX_OUTPUT_ENCODING_CONFIG
40
+ }: {
41
+ address: Address.Address
42
+ assets: Assets.Assets
43
+ datum?: TxOutputDatum.TxOutputDatum
44
+ refScript?: Uint8Array
45
+ encodingConfig?: TxOutputEncodingConfig
46
+ }): TxOutput {
47
+ return {
48
+ _tag: "TxOutput",
49
+ address,
50
+ assets,
51
+ datum,
52
+ refScript,
53
+ encodingConfig
54
+ }
55
+ }
56
+
57
+ export const decode = (bytes: Bytes.BytesLike): Cbor.DecodeEffect<TxOutput> =>
58
+ Effect.gen(function* () {
59
+ const stream = Bytes.makeStream(bytes)
60
+ if (yield* Cbor.isObject(bytes)) {
61
+ const {
62
+ 0: address,
63
+ 1: assets,
64
+ 2: datum,
65
+ 3: refScript
66
+ } = yield* Cbor.decodeObjectIKey({
67
+ 0: Address.decode,
68
+ 1: Assets.decode,
69
+ 2: TxOutputDatum.decode,
70
+ 3: (stream): Cbor.DecodeEffect<number[]> =>
71
+ Effect.gen(function* () {
72
+ if ((yield* Cbor.decodeTag(stream)) != 24n) {
73
+ return yield* new Cbor.DecodeError(
74
+ stream,
75
+ "unexpected reference script tag"
76
+ )
77
+ }
78
+
79
+ return yield* Cbor.decodeBytes(stream)
80
+ })
81
+ })(stream)
82
+
83
+ if (!address) {
84
+ return yield* new Cbor.DecodeError(stream, "address field missing")
85
+ }
86
+
87
+ if (!assets) {
88
+ return yield* new Cbor.DecodeError(stream, "assets field missing")
89
+ }
90
+
91
+ return make({
92
+ address,
93
+ assets,
94
+ ...(datum ? { datum } : {}),
95
+ ...(refScript ? { refScript: new Uint8Array(refScript) } : {}),
96
+ encodingConfig: { strictBabbage: true }
97
+ })
98
+ } else if (yield* Cbor.isTuple(bytes)) {
99
+ const [address, assets, datumHash] = yield* Cbor.decodeTuple(
100
+ [Address.decode, Assets.decode],
101
+ [DatumHash.decode]
102
+ )(stream)
103
+
104
+ return make({
105
+ address,
106
+ assets,
107
+ ...(datumHash ? { _tag: "Hash", hash: datumHash } : {}),
108
+ encodingConfig: {
109
+ strictBabbage: false
110
+ }
111
+ })
112
+ } else {
113
+ return yield* new Cbor.DecodeError(stream, "unexpected TxOutput encoding")
114
+ }
115
+ })
116
+
117
+ export function encode(txOutput: TxOutput): number[] {
118
+ if (
119
+ (!txOutput.datum || txOutput.datum._tag == "Hash") &&
120
+ !txOutput.refScript &&
121
+ !txOutput.encodingConfig.strictBabbage
122
+ ) {
123
+ // this is needed to match eternl wallet (de)serialization (annoyingly eternl deserializes the tx and then signs its own serialization)
124
+ // hopefully cardano-cli signs whatever serialization we choose (so we use the eternl variant in order to be compatible with both)
125
+
126
+ const fields = [
127
+ Address.encode(txOutput.address),
128
+ Assets.encode(txOutput.assets)
129
+ ]
130
+
131
+ if (txOutput.datum && txOutput.datum._tag == "Hash") {
132
+ fields.push(DatumHash.encode(txOutput.datum.hash))
133
+ }
134
+
135
+ return Cbor.encodeTuple(fields)
136
+ } else {
137
+ const object: Map<number, number[]> = new Map()
138
+
139
+ object.set(0, Address.encode(txOutput.address))
140
+ object.set(1, Assets.encode(txOutput.assets))
141
+
142
+ if (txOutput.datum) {
143
+ object.set(2, TxOutputDatum.encode(txOutput.datum))
144
+ }
145
+
146
+ if (txOutput.refScript) {
147
+ throw new Error("not yet implemented")
148
+ //object.set(
149
+ // 3,
150
+ // Cbor.encodeTag(24n).concat(
151
+ // Cbor.encodeBytes(
152
+ // Cbor.encodeTuple([
153
+ // Cbor.encodeInt(
154
+ // BigInt(this.refScript.plutusVersionTag)
155
+ // ),
156
+ // txOutput.refScript
157
+ // ])
158
+ // )
159
+ // )
160
+ //)
161
+ }
162
+
163
+ return Cbor.encodeObjectIKey(object)
164
+ }
165
+ }
@@ -0,0 +1,64 @@
1
+ import { Effect, Schema } from "effect"
2
+ import * as Bytes from "../internal/Bytes.js"
3
+ import * as Cbor from "../Cbor.js"
4
+ import { Data } from "../Uplc"
5
+ import * as DatumHash from "./DatumHash.js"
6
+
7
+ export const TxOutputDatum = Schema.Union(
8
+ Schema.TaggedStruct("Inline", { data: Data.Data }),
9
+ Schema.TaggedStruct("Hash", { hash: DatumHash.DatumHash })
10
+ )
11
+
12
+ export type TxOutputDatum = Schema.Schema.Type<typeof TxOutputDatum>
13
+
14
+ export const decode = (
15
+ bytes: Bytes.BytesLike
16
+ ): Cbor.DecodeEffect<TxOutputDatum> =>
17
+ Effect.gen(function* () {
18
+ const [type, decodeItem] = yield* Cbor.decodeTagged(bytes)
19
+
20
+ switch (type) {
21
+ case 0:
22
+ return { _tag: "Hash", hash: yield* decodeItem(DatumHash.decode) }
23
+ case 1:
24
+ return {
25
+ _tag: "Inline",
26
+ data: yield* decodeItem((stream: Bytes.Stream) =>
27
+ Effect.gen(function* () {
28
+ const tag = yield* Cbor.decodeTag(stream)
29
+ if (tag != 24n) {
30
+ return yield* Effect.fail(
31
+ new Cbor.DecodeError(stream, `expected 24 as tag, got ${tag}`)
32
+ )
33
+ }
34
+
35
+ return yield* Data.decode(yield* Cbor.decodeBytes(stream))
36
+ })
37
+ )
38
+ }
39
+ default:
40
+ return yield* Effect.fail(
41
+ new Cbor.DecodeError(
42
+ Bytes.makeStream(bytes),
43
+ `unhandled TxOutputDatum type ${type}`
44
+ )
45
+ )
46
+ }
47
+ })
48
+
49
+ export function encode(txOutputDatum: TxOutputDatum): number[] {
50
+ switch (txOutputDatum._tag) {
51
+ case "Hash":
52
+ return Cbor.encodeTuple([
53
+ Cbor.encodeInt(0n),
54
+ DatumHash.encode(txOutputDatum.hash)
55
+ ])
56
+ case "Inline":
57
+ return Cbor.encodeTuple([
58
+ Cbor.encodeInt(1n),
59
+ Cbor.encodeTag(24n).concat(
60
+ Cbor.encodeBytes(Data.encode(txOutputDatum.data))
61
+ )
62
+ ])
63
+ }
64
+ }
@@ -0,0 +1,63 @@
1
+ import { Effect, Schema } from "effect"
2
+ import * as Bytes from "../internal/Bytes.js"
3
+ import * as Cbor from "../Cbor.js"
4
+ import * as TxId from "./TxId.js"
5
+
6
+ export function isValid(txOutputId: string): txOutputId is TxOutputId {
7
+ if (txOutputId.length < 65) {
8
+ return false
9
+ }
10
+
11
+ const txId = txOutputId.slice(0, 64)
12
+
13
+ const utxoIdx = parseInt(txOutputId.slice(64))
14
+
15
+ if (utxoIdx.toString() != txOutputId.slice(64)) {
16
+ return false
17
+ }
18
+
19
+ return /^[0-9a-fA-F]+$/.test(txId)
20
+ }
21
+
22
+ export const TxOutputId = Schema.transform(
23
+ Schema.String,
24
+ Schema.String.pipe(
25
+ Schema.filter((id: string) => isValid(id) || "Invalid Cardano TxOutputId"),
26
+ Schema.brand("TxOutputId")
27
+ ),
28
+ {
29
+ strict: false,
30
+ decode: (s) => s.split("#").join(""),
31
+ encode: (s) => s
32
+ }
33
+ )
34
+
35
+ export type TxOutputId = Schema.Schema.Type<typeof TxOutputId>
36
+
37
+ export function make(txId: TxId.TxId, utxoIdx: number | bigint): TxOutputId {
38
+ return (txId + utxoIdx.toString()) as TxOutputId
39
+ }
40
+
41
+ export const decode = (bytes: Bytes.BytesLike): Cbor.DecodeEffect<TxOutputId> =>
42
+ Cbor.decodeTuple([TxId.decode, Cbor.decodeInt])(bytes).pipe(
43
+ Effect.map(([txId, utxoIdx]) => make(txId, utxoIdx))
44
+ )
45
+
46
+ export function encode(txOutputId: TxOutputId): number[] {
47
+ return Cbor.encodeTuple([
48
+ TxId.encode(txId(txOutputId)),
49
+ Cbor.encodeInt(utxoIdx(txOutputId))
50
+ ])
51
+ }
52
+
53
+ export function pretty(txOutputId: TxOutputId): string {
54
+ return txId(txOutputId) + "#" + utxoIdx(txOutputId).toString()
55
+ }
56
+
57
+ export function txId(txOutputId: TxOutputId): TxId.TxId {
58
+ return txOutputId.slice(0, 64) as TxId.TxId
59
+ }
60
+
61
+ export function utxoIdx(txOutputId: TxOutputId): number {
62
+ return parseInt(txOutputId.slice(64))
63
+ }
@@ -0,0 +1,36 @@
1
+ import { Effect, Encoding, Schema } from "effect"
2
+ import * as Bytes from "../internal/Bytes.js"
3
+ import { decodeBytes, DecodeEffect, encodeBytes } from "../Cbor.js"
4
+ import { Data } from "../Uplc"
5
+
6
+ export function isValid(vh: string): boolean {
7
+ return /^[0-9a-fA-F]+$/.test(vh) && vh.length == 56
8
+ }
9
+
10
+ export const ValidatorHash = Schema.String.pipe(
11
+ Schema.filter((vh: string) => isValid(vh) || "Invalid Cardano ValidatorHash"),
12
+ Schema.brand("ValidatorHash")
13
+ )
14
+
15
+ export type ValidatorHash = Schema.Schema.Type<typeof ValidatorHash>
16
+
17
+ export function make(bytes: Bytes.BytesLike) {
18
+ return Schema.decode(ValidatorHash)(Bytes.toHex(bytes))
19
+ }
20
+
21
+ export const FromUplcData = Schema.transform(Data.ByteArray, ValidatorHash, {
22
+ strict: true,
23
+ decode: Encoding.encodeHex,
24
+ encode: Bytes.toUint8Array
25
+ })
26
+
27
+ export const decode = (bytes: Bytes.BytesLike): DecodeEffect<ValidatorHash> =>
28
+ decodeBytes(bytes).pipe(
29
+ Effect.map((bytes) => new Uint8Array(bytes)),
30
+ Effect.map(Encoding.encodeHex),
31
+ Effect.map(Schema.decodeSync(ValidatorHash))
32
+ )
33
+
34
+ export function encode(vh: ValidatorHash): number[] {
35
+ return encodeBytes(vh)
36
+ }
@@ -0,0 +1,13 @@
1
+ export * as Address from "./Address.js"
2
+ export * as AssetClass from "./AssetClass.js"
3
+ export * as Assets from "./Assets.js"
4
+ export * as Credential from "./Credential.js"
5
+ export * as DatumHash from "./DatumHash.js"
6
+ export * as MintingPolicy from "./MintingPolicy.js"
7
+ export * as PubKeyHash from "./PubKeyHash.js"
8
+ export * as TxId from "./TxId.js"
9
+ export * as TxInput from "./TxInput.js"
10
+ export * as TxOutput from "./TxOutput.js"
11
+ export * as TxOutputDatum from "./TxOutputDatum.js"
12
+ export * as TxOutputId from "./TxOutputId.js"
13
+ export * as ValidatorHash from "./ValidatorHash.js"