@helios-lang/effect 0.1.14 → 0.2.0
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.
- package/dist/Cardano/CoinSelection.js +130 -0
- package/dist/Cardano/CoinSelection.js.map +1 -0
- package/dist/{Ledger → Cardano/Ledger}/Address.js +30 -20
- package/dist/Cardano/Ledger/Address.js.map +1 -0
- package/dist/{Ledger → Cardano/Ledger}/AssetClass.js +16 -11
- package/dist/Cardano/Ledger/AssetClass.js.map +1 -0
- package/dist/Cardano/Ledger/Assets.js +235 -0
- package/dist/Cardano/Ledger/Assets.js.map +1 -0
- package/dist/Cardano/Ledger/Credential.js +53 -0
- package/dist/Cardano/Ledger/Credential.js.map +1 -0
- package/dist/Cardano/Ledger/DCert.js +117 -0
- package/dist/Cardano/Ledger/DCert.js.map +1 -0
- package/dist/Cardano/Ledger/DatumHash.js +25 -0
- package/dist/Cardano/Ledger/DatumHash.js.map +1 -0
- package/dist/Cardano/Ledger/MintingPolicy.js +40 -0
- package/dist/Cardano/Ledger/MintingPolicy.js.map +1 -0
- package/dist/Cardano/Ledger/NativeScript.js +140 -0
- package/dist/Cardano/Ledger/NativeScript.js.map +1 -0
- package/dist/Cardano/Ledger/PubKey.js +22 -0
- package/dist/Cardano/Ledger/PubKey.js.map +1 -0
- package/dist/{Ledger → Cardano/Ledger}/PubKeyHash.js +5 -5
- package/dist/Cardano/Ledger/PubKeyHash.js.map +1 -0
- package/dist/Cardano/Ledger/Redeemer.js +155 -0
- package/dist/Cardano/Ledger/Redeemer.js.map +1 -0
- package/dist/Cardano/Ledger/RewardAddress.js +93 -0
- package/dist/Cardano/Ledger/RewardAddress.js.map +1 -0
- package/dist/Cardano/Ledger/Signature.js +23 -0
- package/dist/Cardano/Ledger/Signature.js.map +1 -0
- package/dist/Cardano/Ledger/Tx.js +498 -0
- package/dist/Cardano/Ledger/Tx.js.map +1 -0
- package/dist/Cardano/Ledger/TxHash.js +38 -0
- package/dist/Cardano/Ledger/TxHash.js.map +1 -0
- package/dist/Cardano/Ledger/TxOutput.js +167 -0
- package/dist/Cardano/Ledger/TxOutput.js.map +1 -0
- package/dist/{Ledger → Cardano/Ledger}/TxOutputDatum.js +44 -8
- package/dist/Cardano/Ledger/TxOutputDatum.js.map +1 -0
- package/dist/Cardano/Ledger/UTxO.js +100 -0
- package/dist/Cardano/Ledger/UTxO.js.map +1 -0
- package/dist/{Ledger → Cardano/Ledger}/UTxORef.js +28 -6
- package/dist/Cardano/Ledger/UTxORef.js.map +1 -0
- package/dist/{Ledger → Cardano/Ledger}/ValidatorHash.js +5 -5
- package/dist/Cardano/Ledger/ValidatorHash.js.map +1 -0
- package/dist/{Ledger → Cardano/Ledger}/index.js +5 -0
- package/dist/Cardano/Ledger/index.js.map +1 -0
- package/dist/Cardano/Network/IsMainnet.js.map +1 -0
- package/dist/{Network → Cardano/Network}/Params.js +27 -3
- package/dist/Cardano/Network/Params.js.map +1 -0
- package/dist/Cardano/Network/UTxO.js +20 -0
- package/dist/Cardano/Network/UTxO.js.map +1 -0
- package/dist/Cardano/Network/UTxOsAt.js +4 -0
- package/dist/Cardano/Network/UTxOsAt.js.map +1 -0
- package/dist/Cardano/Network/errors.js +33 -0
- package/dist/Cardano/Network/errors.js.map +1 -0
- package/dist/{Network → Cardano/Network}/index.js +1 -0
- package/dist/Cardano/Network/index.js.map +1 -0
- package/dist/Cardano/TxBuilder.js +946 -0
- package/dist/Cardano/TxBuilder.js.map +1 -0
- package/dist/Cardano/Uplc/Builtins.js +1820 -0
- package/dist/Cardano/Uplc/Builtins.js.map +1 -0
- package/dist/Cardano/Uplc/Cek.js +716 -0
- package/dist/Cardano/Uplc/Cek.js.map +1 -0
- package/dist/Cardano/Uplc/Cost.js +956 -0
- package/dist/Cardano/Uplc/Cost.js.map +1 -0
- package/dist/{Uplc → Cardano/Uplc}/Data.js +143 -22
- package/dist/Cardano/Uplc/Data.js.map +1 -0
- package/dist/Cardano/Uplc/Script.js +118 -0
- package/dist/Cardano/Uplc/Script.js.map +1 -0
- package/dist/Cardano/Uplc/ScriptContext.js +259 -0
- package/dist/Cardano/Uplc/ScriptContext.js.map +1 -0
- package/dist/Cardano/Uplc/Term.js +384 -0
- package/dist/Cardano/Uplc/Term.js.map +1 -0
- package/dist/Cardano/Uplc/Type.js +131 -0
- package/dist/Cardano/Uplc/Type.js.map +1 -0
- package/dist/Cardano/Uplc/Value.js +315 -0
- package/dist/Cardano/Uplc/Value.js.map +1 -0
- package/dist/Cardano/Uplc/index.js +7 -0
- package/dist/Cardano/Uplc/index.js.map +1 -0
- package/dist/Cardano/index.js +6 -0
- package/dist/Cardano/index.js.map +1 -0
- package/dist/{internal → Codecs}/Base32.js +2 -2
- package/dist/Codecs/Base32.js.map +1 -0
- package/dist/{Bech32.js → Codecs/Bech32.js} +2 -2
- package/dist/Codecs/Bech32.js.map +1 -0
- package/dist/Codecs/BigEndian.js.map +1 -0
- package/dist/Codecs/Bits.js.map +1 -0
- package/dist/{internal → Codecs}/Bytes.js +23 -12
- package/dist/Codecs/Bytes.js.map +1 -0
- package/dist/{Cbor.js → Codecs/Cbor.js} +559 -328
- package/dist/Codecs/Cbor.js.map +1 -0
- package/dist/{internal → Codecs}/Flat.js +16 -0
- package/dist/Codecs/Flat.js.map +1 -0
- package/dist/Codecs/Float.js.map +1 -0
- package/dist/Codecs/LittleEndian.js +27 -0
- package/dist/Codecs/LittleEndian.js.map +1 -0
- package/dist/Codecs/Uint64.js +89 -0
- package/dist/Codecs/Uint64.js.map +1 -0
- package/dist/{internal → Codecs}/Utf8.js +7 -2
- package/dist/Codecs/Utf8.js.map +1 -0
- package/dist/Codecs/ZigZag.js +26 -0
- package/dist/Codecs/ZigZag.js.map +1 -0
- package/dist/Codecs/index.js +8 -0
- package/dist/Codecs/index.js.map +1 -0
- package/dist/Crypto/Blake2b.js +156 -0
- package/dist/Crypto/Blake2b.js.map +1 -0
- package/dist/Crypto/Curve.js +92 -0
- package/dist/Crypto/Curve.js.map +1 -0
- package/dist/Crypto/Ed25519.js +323 -0
- package/dist/Crypto/Ed25519.js.map +1 -0
- package/dist/Crypto/EdDSA.js +222 -0
- package/dist/Crypto/EdDSA.js.map +1 -0
- package/dist/Crypto/Field.js +323 -0
- package/dist/Crypto/Field.js.map +1 -0
- package/dist/Crypto/Hmac.js +51 -0
- package/dist/Crypto/Hmac.js.map +1 -0
- package/dist/Crypto/Keccak.js +167 -0
- package/dist/Crypto/Keccak.js.map +1 -0
- package/dist/Crypto/Pbkdf2.js +45 -0
- package/dist/Crypto/Pbkdf2.js.map +1 -0
- package/dist/Crypto/Sha2_256.js +200 -0
- package/dist/Crypto/Sha2_256.js.map +1 -0
- package/dist/Crypto/Sha2_512.js +264 -0
- package/dist/Crypto/Sha2_512.js.map +1 -0
- package/dist/Crypto/Sha3_256.js +10 -0
- package/dist/Crypto/Sha3_256.js.map +1 -0
- package/dist/Crypto/errors.js +9 -0
- package/dist/Crypto/errors.js.map +1 -0
- package/dist/Crypto/index.js +12 -0
- package/dist/Crypto/index.js.map +1 -0
- package/dist/index.js +3 -5
- package/dist/index.js.map +1 -1
- package/package.json +24 -6
- package/tsconfig.build.json +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/types/Cardano/CoinSelection.d.ts +26 -0
- package/types/Cardano/CoinSelection.d.ts.map +1 -0
- package/types/{Ledger → Cardano/Ledger}/Address.d.ts +7 -6
- package/types/Cardano/Ledger/Address.d.ts.map +1 -0
- package/types/{Ledger → Cardano/Ledger}/AssetClass.d.ts +2 -2
- package/types/Cardano/Ledger/AssetClass.d.ts.map +1 -0
- package/types/Cardano/Ledger/Assets.d.ts +114 -0
- package/types/Cardano/Ledger/Assets.d.ts.map +1 -0
- package/types/{Ledger → Cardano/Ledger}/Credential.d.ts +10 -4
- package/types/Cardano/Ledger/Credential.d.ts.map +1 -0
- package/types/Cardano/Ledger/DCert.d.ts +40 -0
- package/types/Cardano/Ledger/DCert.d.ts.map +1 -0
- package/types/{Ledger → Cardano/Ledger}/DatumHash.d.ts +6 -5
- package/types/Cardano/Ledger/DatumHash.d.ts.map +1 -0
- package/types/{Ledger → Cardano/Ledger}/MintingPolicy.d.ts +11 -8
- package/types/Cardano/Ledger/MintingPolicy.d.ts.map +1 -0
- package/types/Cardano/Ledger/NativeScript.d.ts +105 -0
- package/types/Cardano/Ledger/NativeScript.d.ts.map +1 -0
- package/types/Cardano/Ledger/PubKey.d.ts +41 -0
- package/types/Cardano/Ledger/PubKey.d.ts.map +1 -0
- package/types/{Ledger → Cardano/Ledger}/PubKeyHash.d.ts +5 -5
- package/types/Cardano/Ledger/PubKeyHash.d.ts.map +1 -0
- package/types/Cardano/Ledger/Redeemer.d.ts +303 -0
- package/types/Cardano/Ledger/Redeemer.d.ts.map +1 -0
- package/types/Cardano/Ledger/RewardAddress.d.ts +60 -0
- package/types/Cardano/Ledger/RewardAddress.d.ts.map +1 -0
- package/types/Cardano/Ledger/Signature.d.ts +13 -0
- package/types/Cardano/Ledger/Signature.d.ts.map +1 -0
- package/types/Cardano/Ledger/Tx.d.ts +375 -0
- package/types/Cardano/Ledger/Tx.d.ts.map +1 -0
- package/types/{Ledger → Cardano/Ledger}/TxHash.d.ts +35 -5
- package/types/Cardano/Ledger/TxHash.d.ts.map +1 -0
- package/types/Cardano/Ledger/TxOutput.d.ts +438 -0
- package/types/Cardano/Ledger/TxOutput.d.ts.map +1 -0
- package/types/Cardano/Ledger/TxOutputDatum.d.ts +98 -0
- package/types/Cardano/Ledger/TxOutputDatum.d.ts.map +1 -0
- package/types/Cardano/Ledger/UTxO.d.ts +1420 -0
- package/types/Cardano/Ledger/UTxO.d.ts.map +1 -0
- package/types/Cardano/Ledger/UTxORef.d.ts +222 -0
- package/types/Cardano/Ledger/UTxORef.d.ts.map +1 -0
- package/types/{Ledger → Cardano/Ledger}/ValidatorHash.d.ts +5 -5
- package/types/Cardano/Ledger/ValidatorHash.d.ts.map +1 -0
- package/types/{Ledger → Cardano/Ledger}/index.d.ts +5 -0
- package/types/Cardano/Ledger/index.d.ts.map +1 -0
- package/types/Cardano/Network/IsMainnet.d.ts.map +1 -0
- package/types/{Network → Cardano/Network}/Params.d.ts +32 -4
- package/types/Cardano/Network/Params.d.ts.map +1 -0
- package/types/Cardano/Network/UTxO.d.ts +15 -0
- package/types/Cardano/Network/UTxO.d.ts.map +1 -0
- package/types/Cardano/Network/UTxOsAt.d.ts +9 -0
- package/types/Cardano/Network/UTxOsAt.d.ts.map +1 -0
- package/types/Cardano/Network/errors.d.ts +39 -0
- package/types/Cardano/Network/errors.d.ts.map +1 -0
- package/types/{Network → Cardano/Network}/index.d.ts +1 -0
- package/types/Cardano/Network/index.d.ts.map +1 -0
- package/types/Cardano/TxBuilder.d.ts +261 -0
- package/types/Cardano/TxBuilder.d.ts.map +1 -0
- package/types/Cardano/Uplc/Builtins.d.ts +163 -0
- package/types/Cardano/Uplc/Builtins.d.ts.map +1 -0
- package/types/Cardano/Uplc/Cek.d.ts +165 -0
- package/types/Cardano/Uplc/Cek.d.ts.map +1 -0
- package/types/Cardano/Uplc/Cost.d.ts +93 -0
- package/types/Cardano/Uplc/Cost.d.ts.map +1 -0
- package/types/{Uplc → Cardano/Uplc}/Data.d.ts +149 -15
- package/types/Cardano/Uplc/Data.d.ts.map +1 -0
- package/types/Cardano/Uplc/Script.d.ts +87 -0
- package/types/Cardano/Uplc/Script.d.ts.map +1 -0
- package/types/Cardano/Uplc/ScriptContext.d.ts +21 -0
- package/types/Cardano/Uplc/ScriptContext.d.ts.map +1 -0
- package/types/Cardano/Uplc/Term.d.ts +454 -0
- package/types/Cardano/Uplc/Term.d.ts.map +1 -0
- package/types/Cardano/Uplc/Type.d.ts +29 -0
- package/types/Cardano/Uplc/Type.d.ts.map +1 -0
- package/types/Cardano/Uplc/Value.d.ts +152 -0
- package/types/Cardano/Uplc/Value.d.ts.map +1 -0
- package/types/Cardano/Uplc/index.d.ts +7 -0
- package/types/Cardano/Uplc/index.d.ts.map +1 -0
- package/types/Cardano/index.d.ts +6 -0
- package/types/Cardano/index.d.ts.map +1 -0
- package/types/Codecs/Base32.d.ts.map +1 -0
- package/types/Codecs/Bech32.d.ts.map +1 -0
- package/types/Codecs/BigEndian.d.ts.map +1 -0
- package/types/Codecs/Bits.d.ts.map +1 -0
- package/types/{internal → Codecs}/Bytes.d.ts +7 -6
- package/types/Codecs/Bytes.d.ts.map +1 -0
- package/types/{Cbor.d.ts → Codecs/Cbor.d.ts} +77 -55
- package/types/Codecs/Cbor.d.ts.map +1 -0
- package/types/{internal → Codecs}/Flat.d.ts +2 -0
- package/types/Codecs/Flat.d.ts.map +1 -0
- package/types/Codecs/Float.d.ts.map +1 -0
- package/types/Codecs/LittleEndian.d.ts +18 -0
- package/types/Codecs/LittleEndian.d.ts.map +1 -0
- package/types/Codecs/Uint64.d.ts +16 -0
- package/types/Codecs/Uint64.d.ts.map +1 -0
- package/types/{internal → Codecs}/Utf8.d.ts +2 -2
- package/types/Codecs/Utf8.d.ts.map +1 -0
- package/types/Codecs/ZigZag.d.ts +3 -0
- package/types/Codecs/ZigZag.d.ts.map +1 -0
- package/types/Codecs/index.d.ts +8 -0
- package/types/Codecs/index.d.ts.map +1 -0
- package/types/Crypto/Blake2b.d.ts +16 -0
- package/types/Crypto/Blake2b.d.ts.map +1 -0
- package/types/Crypto/Curve.d.ts +161 -0
- package/types/Crypto/Curve.d.ts.map +1 -0
- package/types/Crypto/Ed25519.d.ts +155 -0
- package/types/Crypto/Ed25519.d.ts.map +1 -0
- package/types/Crypto/EdDSA.d.ts +159 -0
- package/types/Crypto/EdDSA.d.ts.map +1 -0
- package/types/Crypto/Field.d.ts +273 -0
- package/types/Crypto/Field.d.ts.map +1 -0
- package/types/Crypto/Hmac.d.ts +20 -0
- package/types/Crypto/Hmac.d.ts.map +1 -0
- package/types/Crypto/Keccak.d.ts +16 -0
- package/types/Crypto/Keccak.d.ts.map +1 -0
- package/types/Crypto/Pbkdf2.d.ts +15 -0
- package/types/Crypto/Pbkdf2.d.ts.map +1 -0
- package/types/Crypto/Sha2_256.d.ts +36 -0
- package/types/Crypto/Sha2_256.d.ts.map +1 -0
- package/types/Crypto/Sha2_512.d.ts +31 -0
- package/types/Crypto/Sha2_512.d.ts.map +1 -0
- package/types/Crypto/Sha3_256.d.ts +8 -0
- package/types/Crypto/Sha3_256.d.ts.map +1 -0
- package/types/Crypto/errors.d.ts +10 -0
- package/types/Crypto/errors.d.ts.map +1 -0
- package/types/Crypto/index.d.ts +12 -0
- package/types/Crypto/index.d.ts.map +1 -0
- package/types/index.d.ts +3 -5
- package/types/index.d.ts.map +1 -1
- package/dist/Address.js +0 -13
- package/dist/Address.js.map +0 -1
- package/dist/Bech32.js.map +0 -1
- package/dist/Cbor.js.map +0 -1
- package/dist/Ledger/Address.js.map +0 -1
- package/dist/Ledger/AssetClass.js.map +0 -1
- package/dist/Ledger/Assets.js +0 -120
- package/dist/Ledger/Assets.js.map +0 -1
- package/dist/Ledger/Credential.js +0 -17
- package/dist/Ledger/Credential.js.map +0 -1
- package/dist/Ledger/DatumHash.js +0 -21
- package/dist/Ledger/DatumHash.js.map +0 -1
- package/dist/Ledger/IsMainnet.js +0 -4
- package/dist/Ledger/IsMainnet.js.map +0 -1
- package/dist/Ledger/MintingPolicy.js +0 -45
- package/dist/Ledger/MintingPolicy.js.map +0 -1
- package/dist/Ledger/NetworkParams.js +0 -40
- package/dist/Ledger/NetworkParams.js.map +0 -1
- package/dist/Ledger/PubKeyHash.js.map +0 -1
- package/dist/Ledger/TxHash.js +0 -23
- package/dist/Ledger/TxHash.js.map +0 -1
- package/dist/Ledger/TxId.js +0 -23
- package/dist/Ledger/TxId.js.map +0 -1
- package/dist/Ledger/TxInput.js +0 -51
- package/dist/Ledger/TxInput.js.map +0 -1
- package/dist/Ledger/TxOutput.js +0 -118
- package/dist/Ledger/TxOutput.js.map +0 -1
- package/dist/Ledger/TxOutputDatum.js.map +0 -1
- package/dist/Ledger/TxOutputId.js +0 -55
- package/dist/Ledger/TxOutputId.js.map +0 -1
- package/dist/Ledger/UTxO.js +0 -43
- package/dist/Ledger/UTxO.js.map +0 -1
- package/dist/Ledger/UTxORef.js.map +0 -1
- package/dist/Ledger/ValidatorHash.js.map +0 -1
- package/dist/Ledger/index.js.map +0 -1
- package/dist/Network/IsMainnet.js.map +0 -1
- package/dist/Network/Params.js.map +0 -1
- package/dist/Network/UTxOsAt.js +0 -4
- package/dist/Network/UTxOsAt.js.map +0 -1
- package/dist/Network/errors.js +0 -16
- package/dist/Network/errors.js.map +0 -1
- package/dist/Network/index.js.map +0 -1
- package/dist/Uplc/Cek.js +0 -3
- package/dist/Uplc/Cek.js.map +0 -1
- package/dist/Uplc/Data.js.map +0 -1
- package/dist/Uplc/DataSchema.js +0 -118
- package/dist/Uplc/DataSchema.js.map +0 -1
- package/dist/Uplc/Primitive.js +0 -23
- package/dist/Uplc/Primitive.js.map +0 -1
- package/dist/Uplc/index.js +0 -3
- package/dist/Uplc/index.js.map +0 -1
- package/dist/internal/Base32.js.map +0 -1
- package/dist/internal/BigEndian.js.map +0 -1
- package/dist/internal/Bits.js.map +0 -1
- package/dist/internal/Bytes.js.map +0 -1
- package/dist/internal/Flat.js.map +0 -1
- package/dist/internal/Float.js.map +0 -1
- package/dist/internal/Utf8.js.map +0 -1
- package/tsconfig.check.tsbuildinfo +0 -1
- package/types/Address.d.ts +0 -5
- package/types/Address.d.ts.map +0 -1
- package/types/Bech32.d.ts.map +0 -1
- package/types/Cbor.d.ts.map +0 -1
- package/types/Ledger/Address.d.ts.map +0 -1
- package/types/Ledger/AssetClass.d.ts.map +0 -1
- package/types/Ledger/Assets.d.ts +0 -70
- package/types/Ledger/Assets.d.ts.map +0 -1
- package/types/Ledger/Credential.d.ts.map +0 -1
- package/types/Ledger/DatumHash.d.ts.map +0 -1
- package/types/Ledger/IsMainnet.d.ts +0 -6
- package/types/Ledger/IsMainnet.d.ts.map +0 -1
- package/types/Ledger/MintingPolicy.d.ts.map +0 -1
- package/types/Ledger/NetworkParams.d.ts +0 -40
- package/types/Ledger/NetworkParams.d.ts.map +0 -1
- package/types/Ledger/PubKeyHash.d.ts.map +0 -1
- package/types/Ledger/TxHash.d.ts.map +0 -1
- package/types/Ledger/TxId.d.ts +0 -70
- package/types/Ledger/TxId.d.ts.map +0 -1
- package/types/Ledger/TxInput.d.ts +0 -55
- package/types/Ledger/TxInput.d.ts.map +0 -1
- package/types/Ledger/TxOutput.d.ts +0 -63
- package/types/Ledger/TxOutput.d.ts.map +0 -1
- package/types/Ledger/TxOutputDatum.d.ts +0 -41
- package/types/Ledger/TxOutputDatum.d.ts.map +0 -1
- package/types/Ledger/TxOutputId.d.ts +0 -133
- package/types/Ledger/TxOutputId.d.ts.map +0 -1
- package/types/Ledger/UTxO.d.ts +0 -55
- package/types/Ledger/UTxO.d.ts.map +0 -1
- package/types/Ledger/UTxORef.d.ts +0 -133
- package/types/Ledger/UTxORef.d.ts.map +0 -1
- package/types/Ledger/ValidatorHash.d.ts.map +0 -1
- package/types/Ledger/index.d.ts.map +0 -1
- package/types/Network/IsMainnet.d.ts.map +0 -1
- package/types/Network/Params.d.ts.map +0 -1
- package/types/Network/UTxOsAt.d.ts +0 -9
- package/types/Network/UTxOsAt.d.ts.map +0 -1
- package/types/Network/errors.d.ts +0 -18
- package/types/Network/errors.d.ts.map +0 -1
- package/types/Network/index.d.ts.map +0 -1
- package/types/Uplc/Cek.d.ts +0 -72
- package/types/Uplc/Cek.d.ts.map +0 -1
- package/types/Uplc/Data.d.ts.map +0 -1
- package/types/Uplc/DataSchema.d.ts +0 -227
- package/types/Uplc/DataSchema.d.ts.map +0 -1
- package/types/Uplc/Primitive.d.ts +0 -26
- package/types/Uplc/Primitive.d.ts.map +0 -1
- package/types/Uplc/index.d.ts +0 -3
- package/types/Uplc/index.d.ts.map +0 -1
- package/types/internal/Base32.d.ts.map +0 -1
- package/types/internal/BigEndian.d.ts.map +0 -1
- package/types/internal/Bits.d.ts.map +0 -1
- package/types/internal/Bytes.d.ts.map +0 -1
- package/types/internal/Flat.d.ts.map +0 -1
- package/types/internal/Float.d.ts.map +0 -1
- package/types/internal/Utf8.d.ts.map +0 -1
- /package/dist/{Network → Cardano/Network}/IsMainnet.js +0 -0
- /package/dist/{internal → Codecs}/BigEndian.js +0 -0
- /package/dist/{internal → Codecs}/Bits.js +0 -0
- /package/dist/{internal → Codecs}/Float.js +0 -0
- /package/types/{Network → Cardano/Network}/IsMainnet.d.ts +0 -0
- /package/types/{internal → Codecs}/Base32.d.ts +0 -0
- /package/types/{Bech32.d.ts → Codecs/Bech32.d.ts} +0 -0
- /package/types/{internal → Codecs}/BigEndian.d.ts +0 -0
- /package/types/{internal → Codecs}/Bits.d.ts +0 -0
- /package/types/{internal → Codecs}/Float.d.ts +0 -0
|
@@ -0,0 +1,946 @@
|
|
|
1
|
+
import { Console, Context, Data, Effect } from "effect";
|
|
2
|
+
import * as CoinSelection from "./CoinSelection.js";
|
|
3
|
+
import { Address, Assets, DCert, MintingPolicy, NativeScript, RewardAddress, Tx, TxOutput, UTxO } from "./Ledger";
|
|
4
|
+
import * as Network from "./Network";
|
|
5
|
+
import * as Uplc from "./Uplc";
|
|
6
|
+
export class UTxOAlreadyAdded extends Data.TaggedError("Cardano.TxBuilder.UTxOAlreadyAdded") {
|
|
7
|
+
constructor(ref) {
|
|
8
|
+
super({ ref, message: `UTxO ${ref} already added to Tx` });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export class MissingDatum extends Data.TaggedError("Cardano.TxBuilder.MissingDatum") {
|
|
12
|
+
constructor() {
|
|
13
|
+
super({ message: "Datum missing" });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class MissingRedeemer extends Data.TaggedError("Cardano.TxBuilder.MissingRedeemer") {
|
|
17
|
+
constructor() {
|
|
18
|
+
super({ message: "Redeemer missing" });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export class RedundantRedeemer extends Data.TaggedError("Cardano.TxBuilder.RedundantRedeemer") {
|
|
22
|
+
constructor() {
|
|
23
|
+
super({
|
|
24
|
+
message: "Redeemer is redundant (input not locked by uplc script)"
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export class RedeemerAlreadyAdded extends Data.TaggedError("Cardano.TxBuilder.RedeemerAlreadyAdded") {
|
|
29
|
+
constructor() {
|
|
30
|
+
super({ message: "Redeemer already added" });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class MissingScript extends Data.TaggedError("Cardano.TxBuilder.MissingScript") {
|
|
34
|
+
constructor(hash) {
|
|
35
|
+
super({ message: `Script missing for ${hash}` });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export class DatumNotFound extends Data.TaggedError("Cardano.TxBuilder.DatumNotFound") {
|
|
39
|
+
constructor(hash, cause) {
|
|
40
|
+
super({ message: `Datum for ${hash} not found (${cause})` });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export class ColleteralNotAvailable extends Data.TaggedError("Cardano.TxBuilder.CollateralNotAvailable") {
|
|
44
|
+
constructor() {
|
|
45
|
+
super({
|
|
46
|
+
message: `Colleteral not available (grabbing colleteral utxos from existing inputs or spare utxos still needs to be implemented)`
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export class GetDatum extends Context.Tag("Cardano.TxBuilder.GetDatum")() {
|
|
51
|
+
}
|
|
52
|
+
const empty = {
|
|
53
|
+
datums: [],
|
|
54
|
+
dcerts: [],
|
|
55
|
+
inputs: [],
|
|
56
|
+
metadata: {},
|
|
57
|
+
minted: {},
|
|
58
|
+
outputs: [],
|
|
59
|
+
refInputs: [],
|
|
60
|
+
mintingRedeemers: [],
|
|
61
|
+
spendingRedeemers: [],
|
|
62
|
+
rewardingRedeemers: [],
|
|
63
|
+
certifyingRedeemers: [],
|
|
64
|
+
nativeScripts: [],
|
|
65
|
+
v1Scripts: [],
|
|
66
|
+
v2Scripts: [],
|
|
67
|
+
v3Scripts: [],
|
|
68
|
+
v2RefScripts: [],
|
|
69
|
+
v3RefScripts: [],
|
|
70
|
+
signers: [],
|
|
71
|
+
validFrom: undefined,
|
|
72
|
+
validTo: undefined,
|
|
73
|
+
withdrawals: []
|
|
74
|
+
};
|
|
75
|
+
export const start = Effect.succeed(empty);
|
|
76
|
+
/**
|
|
77
|
+
* Automatically discards duplicates
|
|
78
|
+
*/
|
|
79
|
+
export const attachScript = (script) => (b) => {
|
|
80
|
+
if ("version" in script) {
|
|
81
|
+
if (Uplc.Script.isVersion(1)(script)) {
|
|
82
|
+
return addV1Script(b, script);
|
|
83
|
+
}
|
|
84
|
+
else if (Uplc.Script.isVersion(2)(script)) {
|
|
85
|
+
return addV2Script(b, script);
|
|
86
|
+
}
|
|
87
|
+
else if (Uplc.Script.isVersion(3)(script)) {
|
|
88
|
+
return addV3Script(b, script);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
throw new Error(`unhandled script version ${script.version}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const hash = NativeScript.hash(script);
|
|
96
|
+
if (hasNativeScript(b, hash)) {
|
|
97
|
+
return b;
|
|
98
|
+
}
|
|
99
|
+
// assign result before returning so that return type is TxBuilder
|
|
100
|
+
b = {
|
|
101
|
+
...b,
|
|
102
|
+
nativeScripts: [...b.nativeScripts, { script, hash }]
|
|
103
|
+
};
|
|
104
|
+
return b;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
export const attachScriptEffect = (script) => Effect.map(attachScript(script));
|
|
108
|
+
export const delegate = (credential, poolId, redeemer = undefined) => (b) => Effect.gen(function* () {
|
|
109
|
+
const dcert = {
|
|
110
|
+
_tag: "Delegation",
|
|
111
|
+
credential,
|
|
112
|
+
poolId
|
|
113
|
+
};
|
|
114
|
+
b = addDCert(b, dcert);
|
|
115
|
+
if (credential._tag == "Validator") {
|
|
116
|
+
if (redeemer) {
|
|
117
|
+
if (hasNativeScript(b, credential.hash)) {
|
|
118
|
+
return yield* Effect.fail(new RedundantRedeemer());
|
|
119
|
+
}
|
|
120
|
+
if (!hasUplcScript(b, credential.hash)) {
|
|
121
|
+
return yield* Effect.fail(new MissingScript(credential.hash));
|
|
122
|
+
}
|
|
123
|
+
b = yield* addCertifyingRedeemer(b, dcert, redeemer);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
if (!hasNativeScript(b, credential.hash)) {
|
|
127
|
+
return yield* Effect.fail(new MissingRedeemer());
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else if (redeemer) {
|
|
132
|
+
return yield* Effect.fail(new RedundantRedeemer());
|
|
133
|
+
}
|
|
134
|
+
return b;
|
|
135
|
+
});
|
|
136
|
+
export const delegateEffect = (credential, poolId, redeemer = undefined) => Effect.flatMap(delegate(credential, poolId, redeemer));
|
|
137
|
+
export const deregister = (credential, redeemer = undefined) => (b) => Effect.gen(function* () {
|
|
138
|
+
const dcert = {
|
|
139
|
+
_tag: "Deregistration",
|
|
140
|
+
credential
|
|
141
|
+
};
|
|
142
|
+
b = addDCert(b, dcert);
|
|
143
|
+
if (credential._tag == "Validator") {
|
|
144
|
+
if (redeemer) {
|
|
145
|
+
if (hasNativeScript(b, credential.hash)) {
|
|
146
|
+
return yield* Effect.fail(new RedundantRedeemer());
|
|
147
|
+
}
|
|
148
|
+
if (!hasUplcScript(b, credential.hash)) {
|
|
149
|
+
return yield* Effect.fail(new MissingScript(credential.hash));
|
|
150
|
+
}
|
|
151
|
+
b = yield* addCertifyingRedeemer(b, dcert, redeemer);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
if (!hasNativeScript(b, credential.hash)) {
|
|
155
|
+
return yield* Effect.fail(new MissingRedeemer());
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else if (redeemer) {
|
|
160
|
+
return yield* Effect.fail(new RedundantRedeemer());
|
|
161
|
+
}
|
|
162
|
+
return b;
|
|
163
|
+
});
|
|
164
|
+
export const deregisterEffect = (credential, redeemer = undefined) => Effect.flatMap(deregister(credential, redeemer));
|
|
165
|
+
export const metadata = (mdata) => (b) => {
|
|
166
|
+
// assign result before returning so that return type is TxBuilder
|
|
167
|
+
b = {
|
|
168
|
+
...b,
|
|
169
|
+
metadata: { ...b.metadata, ...mdata }
|
|
170
|
+
};
|
|
171
|
+
return b;
|
|
172
|
+
};
|
|
173
|
+
export const metadataEffect = (mdata) => Effect.map(metadata(mdata));
|
|
174
|
+
/**
|
|
175
|
+
* Filters out ADA
|
|
176
|
+
* Entries in assets can be negative for burning
|
|
177
|
+
*/
|
|
178
|
+
export const mint = (assets, redeemer = undefined) => (b) => Effect.gen(function* () {
|
|
179
|
+
const policies = Assets.nonAdaPolicies(assets);
|
|
180
|
+
for (const policy of policies) {
|
|
181
|
+
// assign result before returning so that return type is TxBuilder
|
|
182
|
+
b = {
|
|
183
|
+
...b,
|
|
184
|
+
minted: Assets.add(b.minted, Assets.filterByPolicy(policy)(assets))
|
|
185
|
+
};
|
|
186
|
+
const hash = MintingPolicy.hash(policy);
|
|
187
|
+
if (redeemer) {
|
|
188
|
+
if (hasNativeScript(b, hash)) {
|
|
189
|
+
return yield* Effect.fail(new RedundantRedeemer());
|
|
190
|
+
}
|
|
191
|
+
if (!hasUplcScript(b, hash)) {
|
|
192
|
+
return yield* Effect.fail(new MissingScript(hash));
|
|
193
|
+
}
|
|
194
|
+
addMintingRedeemer(b, policy, redeemer);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
if (!hasNativeScript(b, hash)) {
|
|
198
|
+
return yield* Effect.fail(new MissingRedeemer());
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return b;
|
|
203
|
+
});
|
|
204
|
+
export const mintEffect = (assets, redeemer = undefined) => Effect.flatMap(mint(assets, redeemer));
|
|
205
|
+
export const pay = (...outputs) => (b) => Effect.gen(function* () {
|
|
206
|
+
for (const output of outputs) {
|
|
207
|
+
b = yield* addOutput(b, output);
|
|
208
|
+
}
|
|
209
|
+
return b;
|
|
210
|
+
});
|
|
211
|
+
export const payEffect = (...outputs) => Effect.flatMap(pay(...outputs));
|
|
212
|
+
export const refer = (...utxos) => (b) => Effect.gen(function* () {
|
|
213
|
+
for (const utxo of utxos) {
|
|
214
|
+
b = yield* addRefInput(b, utxo);
|
|
215
|
+
const refScript = utxo.output.refScript;
|
|
216
|
+
switch (refScript?.version) {
|
|
217
|
+
case 2:
|
|
218
|
+
b = addV2RefScript(b, refScript);
|
|
219
|
+
break;
|
|
220
|
+
case 3:
|
|
221
|
+
b = addV3RefScript(b, refScript);
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return b;
|
|
226
|
+
});
|
|
227
|
+
export const referEffect = (...utxos) => Effect.flatMap(refer(...utxos));
|
|
228
|
+
export const register = (credential) => (b) => {
|
|
229
|
+
b = addDCert(b, {
|
|
230
|
+
_tag: "Registration",
|
|
231
|
+
credential
|
|
232
|
+
});
|
|
233
|
+
return b;
|
|
234
|
+
};
|
|
235
|
+
export const registerEffect = (credential) => Effect.map(register(credential));
|
|
236
|
+
export const sign = (...signers) => (b) => {
|
|
237
|
+
for (const signer of signers) {
|
|
238
|
+
b = addSigner(b, signer);
|
|
239
|
+
}
|
|
240
|
+
return b;
|
|
241
|
+
};
|
|
242
|
+
export const signEffect = (...signers) => Effect.map(sign(...signers));
|
|
243
|
+
export const spend = (utxos, redeemer = undefined) => (b) => Effect.gen(function* () {
|
|
244
|
+
for (const utxo of Array.isArray(utxos) ? utxos : [utxos]) {
|
|
245
|
+
b = yield* addInput(b, utxo);
|
|
246
|
+
const spendingCred = Address.spendingCredential(utxo.output.address);
|
|
247
|
+
if (redeemer) {
|
|
248
|
+
if (spendingCred._tag != "Validator") {
|
|
249
|
+
return yield* Effect.fail(new RedundantRedeemer());
|
|
250
|
+
}
|
|
251
|
+
if (!hasUplcScript(b, spendingCred.hash)) {
|
|
252
|
+
return yield* Effect.fail(new MissingScript(spendingCred.hash));
|
|
253
|
+
}
|
|
254
|
+
b = yield* addSpendingRedeemer(b, utxo, redeemer);
|
|
255
|
+
const datum = utxo.output.datum;
|
|
256
|
+
if (!datum && !hasDatumlessScript(b, spendingCred.hash)) {
|
|
257
|
+
return yield* Effect.fail(new MissingDatum());
|
|
258
|
+
}
|
|
259
|
+
if (datum && datum._tag == "Hash") {
|
|
260
|
+
// provide datum through service
|
|
261
|
+
const getDatum = yield* GetDatum;
|
|
262
|
+
const datumData = yield* getDatum(datum.hash);
|
|
263
|
+
b = addDatum(b, datumData);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
else if (spendingCred._tag == "Validator") {
|
|
267
|
+
if (!hasNativeScript(b, spendingCred.hash)) {
|
|
268
|
+
return yield* Effect.fail(new MissingRedeemer());
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return b;
|
|
273
|
+
});
|
|
274
|
+
export const spendEffect = (utxos, redeemer = undefined) => Effect.flatMap(spend(utxos, redeemer));
|
|
275
|
+
export const validFromSlot = (slot) => (b) => {
|
|
276
|
+
// assign result before returning so that return type is TxBuilder
|
|
277
|
+
b = {
|
|
278
|
+
...b,
|
|
279
|
+
validFrom: { slot }
|
|
280
|
+
};
|
|
281
|
+
return b;
|
|
282
|
+
};
|
|
283
|
+
export const validFromSlotEffect = (slot) => Effect.map(validFromSlot(slot));
|
|
284
|
+
/**
|
|
285
|
+
* @param time
|
|
286
|
+
* Milliseconds since 1970
|
|
287
|
+
*/
|
|
288
|
+
export const validFromTime = (time) => (b) => {
|
|
289
|
+
// assign result before returning so that return type is TxBuilder
|
|
290
|
+
b = {
|
|
291
|
+
...b,
|
|
292
|
+
validFrom: { time }
|
|
293
|
+
};
|
|
294
|
+
return b;
|
|
295
|
+
};
|
|
296
|
+
export const validFromTimeEffect = (time) => Effect.map(validFromTime(time));
|
|
297
|
+
export const validToSlot = (slot) => (b) => {
|
|
298
|
+
// assign result before returning so that return type is TxBuilder
|
|
299
|
+
b = {
|
|
300
|
+
...b,
|
|
301
|
+
validTo: { slot }
|
|
302
|
+
};
|
|
303
|
+
return b;
|
|
304
|
+
};
|
|
305
|
+
export const validToSlotEffect = (slot) => Effect.map(validToSlot(slot));
|
|
306
|
+
/**
|
|
307
|
+
* @param time
|
|
308
|
+
* Milliseconds since 1970
|
|
309
|
+
*/
|
|
310
|
+
export const validToTime = (time) => (b) => {
|
|
311
|
+
// assign result before returning so that return type is TxBuilder
|
|
312
|
+
b = {
|
|
313
|
+
...b,
|
|
314
|
+
validTo: { time }
|
|
315
|
+
};
|
|
316
|
+
return b;
|
|
317
|
+
};
|
|
318
|
+
export const validToTimeEffect = (time) => Effect.map(validToTime(time));
|
|
319
|
+
export const withdraw = (rewardAddress, lovelace, redeemer = undefined) => (b) => Effect.gen(function* () {
|
|
320
|
+
const i = b.withdrawals.findIndex((w) => w.address == rewardAddress);
|
|
321
|
+
if (redeemer) {
|
|
322
|
+
if (RewardAddress.credential(rewardAddress)._tag != "Validator") {
|
|
323
|
+
throw new Error("can't withdraw using redeemer from non-Validator rewards address");
|
|
324
|
+
}
|
|
325
|
+
b = yield* addRewardingRedeemer(b, rewardAddress, redeemer);
|
|
326
|
+
}
|
|
327
|
+
const withdrawals = b.withdrawals.slice();
|
|
328
|
+
if (i == -1) {
|
|
329
|
+
withdrawals.push({ address: rewardAddress, lovelace: BigInt(lovelace) });
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
withdrawals[i] = {
|
|
333
|
+
address: rewardAddress,
|
|
334
|
+
lovelace: BigInt(lovelace) + withdrawals[i].lovelace
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
withdrawals.sort(({ address: a }, { address: b }) => RewardAddress.compare(a, b));
|
|
338
|
+
// assign result before returning so that return type is TxBuilder
|
|
339
|
+
b = {
|
|
340
|
+
...b,
|
|
341
|
+
withdrawals
|
|
342
|
+
};
|
|
343
|
+
return b;
|
|
344
|
+
});
|
|
345
|
+
export const withdrawEffect = (rewardAddress, lovelace, redeemer = undefined) => Effect.flatMap(withdraw(rewardAddress, lovelace, redeemer));
|
|
346
|
+
function addDatum(b, data) {
|
|
347
|
+
if (hasDatum(b, data)) {
|
|
348
|
+
return b;
|
|
349
|
+
}
|
|
350
|
+
// assign result before returning so that return type is TxBuilder
|
|
351
|
+
b = {
|
|
352
|
+
...b,
|
|
353
|
+
datums: [...b.datums, data]
|
|
354
|
+
};
|
|
355
|
+
return b;
|
|
356
|
+
}
|
|
357
|
+
function hasDatum(b, data) {
|
|
358
|
+
return b.datums.some((d) => Uplc.Data.equals(d, data));
|
|
359
|
+
}
|
|
360
|
+
function addDCert(b, dcert) {
|
|
361
|
+
// assign result before returning so that return type is TxBuilder
|
|
362
|
+
b = {
|
|
363
|
+
...b,
|
|
364
|
+
dcerts: [...b.dcerts, dcert]
|
|
365
|
+
};
|
|
366
|
+
if (dcert._tag == "Delegation" || dcert._tag == "Deregistration") {
|
|
367
|
+
if (dcert.credential._tag == "PubKey") {
|
|
368
|
+
b = addSigner(b, dcert.credential.hash);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return b;
|
|
372
|
+
}
|
|
373
|
+
const addInput = (b, input) => Effect.gen(function* () {
|
|
374
|
+
yield* Assets.assertAllPositive(input.output.assets);
|
|
375
|
+
if (hasInput(b, input.ref)) {
|
|
376
|
+
return yield* Effect.fail(new UTxOAlreadyAdded(input.ref));
|
|
377
|
+
}
|
|
378
|
+
if (hasRefInput(b, input.ref)) {
|
|
379
|
+
return yield* Effect.fail(new UTxOAlreadyAdded(input.ref));
|
|
380
|
+
}
|
|
381
|
+
// assign result before returning so that return type is TxBuilder
|
|
382
|
+
b = {
|
|
383
|
+
...b,
|
|
384
|
+
inputs: UTxO.append(b.inputs, input)
|
|
385
|
+
};
|
|
386
|
+
return b;
|
|
387
|
+
});
|
|
388
|
+
function hasInput(b, ref) {
|
|
389
|
+
return b.inputs.some((utxo) => utxo.ref == ref);
|
|
390
|
+
}
|
|
391
|
+
const addRefInput = (b, refInput) => Effect.gen(function* () {
|
|
392
|
+
yield* Assets.assertAllPositive(refInput.output.assets);
|
|
393
|
+
if (b.inputs.some((utxo) => utxo.ref == refInput.ref)) {
|
|
394
|
+
return yield* Effect.fail(new UTxOAlreadyAdded(refInput.ref));
|
|
395
|
+
}
|
|
396
|
+
if (b.refInputs.some((utxo) => utxo.ref == refInput.ref)) {
|
|
397
|
+
return yield* Effect.fail(new UTxOAlreadyAdded(refInput.ref));
|
|
398
|
+
}
|
|
399
|
+
// assign result before returning so that return type is TxBuilder
|
|
400
|
+
b = {
|
|
401
|
+
...b,
|
|
402
|
+
refInputs: UTxO.append(b.refInputs, refInput)
|
|
403
|
+
};
|
|
404
|
+
return b;
|
|
405
|
+
});
|
|
406
|
+
function hasRefInput(b, ref) {
|
|
407
|
+
return b.refInputs.some((utxo) => utxo.ref == ref);
|
|
408
|
+
}
|
|
409
|
+
const addOutput = (b, output) => Effect.gen(function* () {
|
|
410
|
+
yield* Assets.assertAllPositive(output.assets);
|
|
411
|
+
const outputCred = Address.spendingCredential(output.address);
|
|
412
|
+
if (outputCred._tag == "Validator" && output.datum === undefined) {
|
|
413
|
+
yield* Console.warn("TxOutput is sent to validator but doesn't have a datum");
|
|
414
|
+
}
|
|
415
|
+
// assign result before returning so that return type is TxBuilder
|
|
416
|
+
b = {
|
|
417
|
+
...b,
|
|
418
|
+
outputs: [...b.outputs, output]
|
|
419
|
+
};
|
|
420
|
+
return b;
|
|
421
|
+
});
|
|
422
|
+
function addCertifyingRedeemer(b, dcert, redeemer) {
|
|
423
|
+
if (hasCertifyingRedeemer(b, dcert)) {
|
|
424
|
+
return Effect.fail(new RedeemerAlreadyAdded());
|
|
425
|
+
}
|
|
426
|
+
b = {
|
|
427
|
+
...b,
|
|
428
|
+
certifyingRedeemers: [...b.certifyingRedeemers, { dcert, redeemer }]
|
|
429
|
+
};
|
|
430
|
+
return Effect.succeed(b);
|
|
431
|
+
}
|
|
432
|
+
function hasCertifyingRedeemer(b, dcert) {
|
|
433
|
+
return b.dcerts.some((d) => DCert.equals(d, dcert));
|
|
434
|
+
}
|
|
435
|
+
function addMintingRedeemer(b, policy, redeemer) {
|
|
436
|
+
if (hasMintingRedeemer(b, policy)) {
|
|
437
|
+
return Effect.fail(new RedeemerAlreadyAdded());
|
|
438
|
+
}
|
|
439
|
+
// assign result before returning so that return type is TxBuilder
|
|
440
|
+
b = {
|
|
441
|
+
...b,
|
|
442
|
+
mintingRedeemers: [...b.mintingRedeemers, { policy, redeemer }]
|
|
443
|
+
};
|
|
444
|
+
return Effect.succeed(b);
|
|
445
|
+
}
|
|
446
|
+
function hasMintingRedeemer(b, policy) {
|
|
447
|
+
return b.mintingRedeemers.some((r) => r.policy == policy);
|
|
448
|
+
}
|
|
449
|
+
function addRewardingRedeemer(b, addr, redeemer) {
|
|
450
|
+
if (hasRewardingRedeemer(b, addr)) {
|
|
451
|
+
return Effect.fail(new RedeemerAlreadyAdded());
|
|
452
|
+
}
|
|
453
|
+
// assign result before returning so that return type is TxBuilder
|
|
454
|
+
b = {
|
|
455
|
+
...b,
|
|
456
|
+
rewardingRedeemers: [...b.rewardingRedeemers, { addr, redeemer }]
|
|
457
|
+
};
|
|
458
|
+
return Effect.succeed(b);
|
|
459
|
+
}
|
|
460
|
+
function hasRewardingRedeemer(b, addr) {
|
|
461
|
+
return b.rewardingRedeemers.some((r) => r.addr == addr);
|
|
462
|
+
}
|
|
463
|
+
function addSpendingRedeemer(b, utxo, redeemer) {
|
|
464
|
+
if (hasSpendingRedeemer(b, utxo)) {
|
|
465
|
+
return Effect.fail(new RedeemerAlreadyAdded());
|
|
466
|
+
}
|
|
467
|
+
// assign result before returning so that return type is TxBuilder
|
|
468
|
+
b = {
|
|
469
|
+
...b,
|
|
470
|
+
spendingRedeemers: [...b.spendingRedeemers, { utxo, redeemer }]
|
|
471
|
+
};
|
|
472
|
+
return Effect.succeed(b);
|
|
473
|
+
}
|
|
474
|
+
function hasSpendingRedeemer(b, utxo) {
|
|
475
|
+
return b.spendingRedeemers.some((r) => r.utxo.ref == utxo.ref);
|
|
476
|
+
}
|
|
477
|
+
function hasRedeemers(b) {
|
|
478
|
+
return (b.certifyingRedeemers.length > 0 ||
|
|
479
|
+
b.mintingRedeemers.length > 0 ||
|
|
480
|
+
b.rewardingRedeemers.length > 0 ||
|
|
481
|
+
b.spendingRedeemers.length > 0);
|
|
482
|
+
}
|
|
483
|
+
function addV1Script(b, script) {
|
|
484
|
+
const hash = Uplc.Script.hash(script);
|
|
485
|
+
if (hasV1Script(b, hash)) {
|
|
486
|
+
return b;
|
|
487
|
+
}
|
|
488
|
+
// assign result before returning so that return type is TxBuilder
|
|
489
|
+
b = {
|
|
490
|
+
...b,
|
|
491
|
+
v1Scripts: [...b.v1Scripts, { script, hash }]
|
|
492
|
+
};
|
|
493
|
+
return b;
|
|
494
|
+
}
|
|
495
|
+
function hasV1Script(b, hash) {
|
|
496
|
+
return b.v1Scripts.some((s) => s.hash == hash);
|
|
497
|
+
}
|
|
498
|
+
function addV2Script(b, script) {
|
|
499
|
+
const hash = Uplc.Script.hash(script);
|
|
500
|
+
if (hasV2Script(b, hash)) {
|
|
501
|
+
return b;
|
|
502
|
+
}
|
|
503
|
+
// assign result before returning so that return type is TxBuilder
|
|
504
|
+
b = {
|
|
505
|
+
...b,
|
|
506
|
+
v2Scripts: [...b.v2Scripts, { script, hash }]
|
|
507
|
+
};
|
|
508
|
+
return b;
|
|
509
|
+
}
|
|
510
|
+
function hasV2Script(b, hash) {
|
|
511
|
+
return b.v2Scripts.some((s) => s.hash == hash);
|
|
512
|
+
}
|
|
513
|
+
function addV3Script(b, script) {
|
|
514
|
+
const hash = Uplc.Script.hash(script);
|
|
515
|
+
if (hasV3Script(b, hash)) {
|
|
516
|
+
return b;
|
|
517
|
+
}
|
|
518
|
+
// assign result before returning so that return type is TxBuilder
|
|
519
|
+
b = {
|
|
520
|
+
...b,
|
|
521
|
+
v3Scripts: [...b.v3Scripts, { script, hash }]
|
|
522
|
+
};
|
|
523
|
+
return b;
|
|
524
|
+
}
|
|
525
|
+
function hasV3Script(b, hash) {
|
|
526
|
+
return b.v3Scripts.some((s) => s.hash == hash);
|
|
527
|
+
}
|
|
528
|
+
function addV2RefScript(b, script) {
|
|
529
|
+
const hash = Uplc.Script.hash(script);
|
|
530
|
+
if (hasV2RefScript(b, hash)) {
|
|
531
|
+
return b;
|
|
532
|
+
}
|
|
533
|
+
// assign result before returning so that return type is TxBuilder
|
|
534
|
+
b = {
|
|
535
|
+
...b,
|
|
536
|
+
v2RefScripts: [...b.v2RefScripts, { hash, script }]
|
|
537
|
+
};
|
|
538
|
+
return b;
|
|
539
|
+
}
|
|
540
|
+
function hasV2RefScript(b, hash) {
|
|
541
|
+
return b.v2RefScripts.some((s) => s.hash == hash);
|
|
542
|
+
}
|
|
543
|
+
function addV3RefScript(b, script) {
|
|
544
|
+
const hash = Uplc.Script.hash(script);
|
|
545
|
+
if (hasV3RefScript(b, hash)) {
|
|
546
|
+
return b;
|
|
547
|
+
}
|
|
548
|
+
// assign result before returning so that return type is TxBuilder
|
|
549
|
+
b = {
|
|
550
|
+
...b,
|
|
551
|
+
v3RefScripts: [...b.v3RefScripts, { hash, script }]
|
|
552
|
+
};
|
|
553
|
+
return b;
|
|
554
|
+
}
|
|
555
|
+
function hasV3RefScript(b, hash) {
|
|
556
|
+
return b.v3RefScripts.some((s) => s.hash == hash);
|
|
557
|
+
}
|
|
558
|
+
function hasDatumlessScript(b, hash) {
|
|
559
|
+
return (hasNativeScript(b, hash) || hasV3Script(b, hash) || hasV3RefScript(b, hash));
|
|
560
|
+
}
|
|
561
|
+
function hasNativeScript(b, hash) {
|
|
562
|
+
return b.nativeScripts.some((s) => s.hash == hash);
|
|
563
|
+
}
|
|
564
|
+
function hasUplcScript(b, hash) {
|
|
565
|
+
return (hasV1Script(b, hash) ||
|
|
566
|
+
hasV2Script(b, hash) ||
|
|
567
|
+
hasV3Script(b, hash) ||
|
|
568
|
+
hasV2RefScript(b, hash) ||
|
|
569
|
+
hasV3RefScript(b, hash));
|
|
570
|
+
}
|
|
571
|
+
function allUplcScripts(b) {
|
|
572
|
+
return []
|
|
573
|
+
.concat(b.v1Scripts)
|
|
574
|
+
.concat(b.v2Scripts)
|
|
575
|
+
.concat(b.v3Scripts)
|
|
576
|
+
.concat(b.v2RefScripts)
|
|
577
|
+
.concat(b.v3RefScripts);
|
|
578
|
+
}
|
|
579
|
+
function getUplcScript(b, hash) {
|
|
580
|
+
const script = allUplcScripts(b).find((s) => s.hash == hash);
|
|
581
|
+
if (!script) {
|
|
582
|
+
throw new Error(`script with hash '${hash}' not found during redeemer building stage`);
|
|
583
|
+
}
|
|
584
|
+
return script.script;
|
|
585
|
+
}
|
|
586
|
+
function addSigner(b, signer) {
|
|
587
|
+
if (hasSigner(b, signer)) {
|
|
588
|
+
return b;
|
|
589
|
+
}
|
|
590
|
+
// assign result before returning so that return type is TxBuilder
|
|
591
|
+
b = {
|
|
592
|
+
...b,
|
|
593
|
+
signers: [...b.signers, signer]
|
|
594
|
+
};
|
|
595
|
+
return b;
|
|
596
|
+
}
|
|
597
|
+
function hasSigner(b, signer) {
|
|
598
|
+
return b.signers.includes(signer);
|
|
599
|
+
}
|
|
600
|
+
class CurrentTxBuilder extends Context.Tag("Cardano.TxBuilder.CurrentTxBuilder")() {
|
|
601
|
+
}
|
|
602
|
+
export const build = (config) => (b) => Effect.gen(function* () {
|
|
603
|
+
/**
|
|
604
|
+
* Calculate the metadata hash
|
|
605
|
+
*/
|
|
606
|
+
const { metadata, metadataHash } = yield* buildMetadata;
|
|
607
|
+
/**
|
|
608
|
+
* Calculate the validity time range slots
|
|
609
|
+
*/
|
|
610
|
+
const { firstValidSlot, lastValidSlot } = yield* buildValidityTimeRange;
|
|
611
|
+
/**
|
|
612
|
+
* Make sure the outputs contain enough lovelace
|
|
613
|
+
*/
|
|
614
|
+
const outputs = yield* buildNonChangeOutputs;
|
|
615
|
+
/**
|
|
616
|
+
* Simple select a collateral input from the params if smart
|
|
617
|
+
*/
|
|
618
|
+
const collateralInputs = yield* selectCollateralInputs;
|
|
619
|
+
/**
|
|
620
|
+
* Create an unbalanced tx. In this tx a few fields are not yet final:
|
|
621
|
+
* - inputs
|
|
622
|
+
* - outputs
|
|
623
|
+
* - fee
|
|
624
|
+
* - scriptDataHash
|
|
625
|
+
* - redeemers
|
|
626
|
+
*/
|
|
627
|
+
let tx = {
|
|
628
|
+
body: {
|
|
629
|
+
inputs: b.inputs,
|
|
630
|
+
outputs,
|
|
631
|
+
fee: 0n,
|
|
632
|
+
firstValidSlot,
|
|
633
|
+
lastValidSlot,
|
|
634
|
+
dcerts: b.dcerts,
|
|
635
|
+
scriptDataHash: hasRedeemers(b)
|
|
636
|
+
? new Array(32).fill(0)
|
|
637
|
+
: undefined,
|
|
638
|
+
withdrawals: b.withdrawals.map((w) => [w.address, w.lovelace]),
|
|
639
|
+
minted: b.minted,
|
|
640
|
+
refInputs: b.refInputs,
|
|
641
|
+
totalCollateral: 0n,
|
|
642
|
+
collateral: collateralInputs,
|
|
643
|
+
signers: b.signers,
|
|
644
|
+
collateralReturn: undefined, // TODO
|
|
645
|
+
metadataHash,
|
|
646
|
+
encoding: config.bodyEncoding
|
|
647
|
+
},
|
|
648
|
+
witnesses: {
|
|
649
|
+
signatures: [],
|
|
650
|
+
datums: b.datums,
|
|
651
|
+
redeemers: [],
|
|
652
|
+
nativeScripts: b.nativeScripts.map((s) => s.script),
|
|
653
|
+
v1Scripts: b.v1Scripts.map((s) => s.script),
|
|
654
|
+
v2Scripts: b.v2Scripts.map((s) => s.script),
|
|
655
|
+
v3Scripts: b.v3Scripts.map((s) => s.script),
|
|
656
|
+
v2RefScripts: b.v2RefScripts.map((s) => s.script),
|
|
657
|
+
v3RefScripts: b.v3RefScripts.map((s) => s.script),
|
|
658
|
+
encoding: config.witnessesEncoding
|
|
659
|
+
},
|
|
660
|
+
isValid: false,
|
|
661
|
+
metadata
|
|
662
|
+
};
|
|
663
|
+
/**
|
|
664
|
+
* The redeemer indices depend on some tx body fields, so are initialized after the init tx is created
|
|
665
|
+
*/
|
|
666
|
+
tx = yield* buildRedeemersWithoutCost(tx);
|
|
667
|
+
/**
|
|
668
|
+
* Now in a loop the transaction is updated:
|
|
669
|
+
* - fee is set to min fee
|
|
670
|
+
* - the tx is balanced, grabbing inputs from the spareUTxOs and creating a change UTxO if there wasn't already a change UTxO
|
|
671
|
+
* - any lazy redeemer data is built (usually depends on order of inputs/outputs etc.)
|
|
672
|
+
* - the cost of each redeemer is calculated
|
|
673
|
+
* - the scriptDataHash is updated
|
|
674
|
+
*
|
|
675
|
+
* The loop continues as long as the tx.fee field is smaller than the min required field.
|
|
676
|
+
* We know that this loop will run at least once because initially tx.fee=0n, ensuring the tx is balanced
|
|
677
|
+
*/
|
|
678
|
+
while (tx.body.fee < (yield* Tx.minFee(tx))) {
|
|
679
|
+
tx = yield* updateFee(tx);
|
|
680
|
+
tx = yield* balanceTx(tx, config);
|
|
681
|
+
tx = yield* buildRedeemersWithCost(tx);
|
|
682
|
+
tx = yield* updateScriptDataHash(tx);
|
|
683
|
+
}
|
|
684
|
+
return tx;
|
|
685
|
+
}).pipe(Effect.provideService(CurrentTxBuilder, b));
|
|
686
|
+
const buildMetadata = CurrentTxBuilder.pipe(Effect.map((b) => {
|
|
687
|
+
if (b.metadata !== undefined) {
|
|
688
|
+
return { metadata: b.metadata, metadataHash: Tx.hashMetadata(b.metadata) };
|
|
689
|
+
}
|
|
690
|
+
else {
|
|
691
|
+
return { metadata: undefined, metadataHash: undefined };
|
|
692
|
+
}
|
|
693
|
+
}));
|
|
694
|
+
const buildValidityTimeRange = CurrentTxBuilder.pipe(Effect.flatMap((b) => {
|
|
695
|
+
const calcSlot = (slotOrTime) => {
|
|
696
|
+
if (slotOrTime === undefined) {
|
|
697
|
+
return Effect.succeed(undefined);
|
|
698
|
+
}
|
|
699
|
+
else if ("time" in slotOrTime) {
|
|
700
|
+
return Network.Params.timeToSlot(slotOrTime.time);
|
|
701
|
+
}
|
|
702
|
+
else {
|
|
703
|
+
return Effect.succeed(slotOrTime.slot);
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
return Effect.zip(calcSlot(b.validFrom), calcSlot(b.validTo)).pipe(Effect.map(([firstValidSlot, lastValidSlot]) => ({
|
|
707
|
+
firstValidSlot,
|
|
708
|
+
lastValidSlot
|
|
709
|
+
})));
|
|
710
|
+
}));
|
|
711
|
+
const buildNonChangeOutputs = Effect.gen(function* () {
|
|
712
|
+
const b = yield* CurrentTxBuilder;
|
|
713
|
+
const outputs = b.outputs.slice();
|
|
714
|
+
for (let i = 0; i < outputs.length; i++) {
|
|
715
|
+
const output = outputs[i];
|
|
716
|
+
const lovelace = yield* TxOutput.minLovelace(output);
|
|
717
|
+
if (lovelace > output.assets[""]) {
|
|
718
|
+
outputs[i] = {
|
|
719
|
+
...output,
|
|
720
|
+
assets: {
|
|
721
|
+
...output.assets,
|
|
722
|
+
"": lovelace
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
return outputs;
|
|
728
|
+
});
|
|
729
|
+
const selectCollateralInputs = Effect.gen(function* () {
|
|
730
|
+
const b = yield* CurrentTxBuilder;
|
|
731
|
+
if (!hasRedeemers(b)) {
|
|
732
|
+
return [];
|
|
733
|
+
}
|
|
734
|
+
else {
|
|
735
|
+
const params = yield* Network.Params.params;
|
|
736
|
+
const ref = params.collateralUTXO;
|
|
737
|
+
if (!ref) {
|
|
738
|
+
return yield* Effect.fail(new ColleteralNotAvailable());
|
|
739
|
+
}
|
|
740
|
+
return [yield* (yield* Network.UTxO)(ref)];
|
|
741
|
+
}
|
|
742
|
+
});
|
|
743
|
+
const buildRedeemersWithoutCost = (tx) => CurrentTxBuilder.pipe(Effect.map((b) => {
|
|
744
|
+
const redeemers = b.mintingRedeemers
|
|
745
|
+
.map((r) => ({
|
|
746
|
+
_tag: "Minting",
|
|
747
|
+
policyIndex: Assets.nonAdaPolicies(tx.body.minted).indexOf(r.policy),
|
|
748
|
+
data: typeof r.redeemer == "function" ? r.redeemer(tx) : r.redeemer,
|
|
749
|
+
cost: { cpu: 0n, mem: 0n }
|
|
750
|
+
}))
|
|
751
|
+
.concat(b.spendingRedeemers.map((r) => ({
|
|
752
|
+
_tag: "Spending",
|
|
753
|
+
inputIndex: tx.body.inputs.map((u) => u.ref).indexOf(r.utxo.ref),
|
|
754
|
+
data: typeof r.redeemer == "function" ? r.redeemer(tx) : r.redeemer,
|
|
755
|
+
cost: { cpu: 0n, mem: 0n }
|
|
756
|
+
})))
|
|
757
|
+
.concat(b.rewardingRedeemers.map((r) => ({
|
|
758
|
+
_tag: "Rewarding",
|
|
759
|
+
withdrawalIndex: tx.body.withdrawals
|
|
760
|
+
.map((w) => w[0])
|
|
761
|
+
.indexOf(r.addr),
|
|
762
|
+
data: typeof r.redeemer == "function" ? r.redeemer(tx) : r.redeemer,
|
|
763
|
+
cost: { cpu: 0n, mem: 0n }
|
|
764
|
+
})))
|
|
765
|
+
.concat(b.certifyingRedeemers.map((r) => ({
|
|
766
|
+
_tag: "Certifying",
|
|
767
|
+
dcertIndex: tx.body.dcerts.findIndex((dcert) => DCert.equals(dcert, r.dcert)),
|
|
768
|
+
data: typeof r.redeemer == "function" ? r.redeemer(tx) : r.redeemer,
|
|
769
|
+
cost: { cpu: 0n, mem: 0n }
|
|
770
|
+
})));
|
|
771
|
+
// assign result before returning so that return type is Tx
|
|
772
|
+
tx = {
|
|
773
|
+
...tx,
|
|
774
|
+
witnesses: {
|
|
775
|
+
...tx.witnesses,
|
|
776
|
+
redeemers
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
return tx;
|
|
780
|
+
}));
|
|
781
|
+
const redeemerInfos = (b) => b.mintingRedeemers
|
|
782
|
+
.concat(b.spendingRedeemers)
|
|
783
|
+
.concat(b.rewardingRedeemers)
|
|
784
|
+
.concat(b.certifyingRedeemers);
|
|
785
|
+
const buildRedeemersWithCost = (tx) => Effect.gen(function* () {
|
|
786
|
+
const b = yield* CurrentTxBuilder;
|
|
787
|
+
/**
|
|
788
|
+
* Rebuild the redeemers to make sure the indices point to the correct policy/input/withdrawal/dcert
|
|
789
|
+
*/
|
|
790
|
+
tx = yield* buildRedeemersWithoutCost(tx);
|
|
791
|
+
/**
|
|
792
|
+
* Now calculate the cost of each redeemer
|
|
793
|
+
*/
|
|
794
|
+
const costs = yield* Effect.all(redeemerInfos(b).map(redeemerValidatorHash).map(profileRedeemer(b, tx)));
|
|
795
|
+
// assign result before returning so that return type is Tx
|
|
796
|
+
tx = {
|
|
797
|
+
...tx,
|
|
798
|
+
witnesses: {
|
|
799
|
+
...tx.witnesses,
|
|
800
|
+
redeemers: tx.witnesses.redeemers.map((r, i) => ({
|
|
801
|
+
...r,
|
|
802
|
+
cost: costs[i]
|
|
803
|
+
}))
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
return tx;
|
|
807
|
+
});
|
|
808
|
+
const redeemerValidatorHash = (redeemer) => {
|
|
809
|
+
if ("policy" in redeemer) {
|
|
810
|
+
return MintingPolicy.hash(redeemer.policy);
|
|
811
|
+
}
|
|
812
|
+
else if ("utxo" in redeemer) {
|
|
813
|
+
const cred = Address.spendingCredential(redeemer.utxo.output.address);
|
|
814
|
+
if (cred._tag != "Validator") {
|
|
815
|
+
throw new Error("unexpected pubkey address for utxo being spent by redeemer");
|
|
816
|
+
}
|
|
817
|
+
return cred.hash;
|
|
818
|
+
}
|
|
819
|
+
else if ("addr" in redeemer) {
|
|
820
|
+
const cred = RewardAddress.credential(redeemer.addr);
|
|
821
|
+
if (cred._tag != "Validator") {
|
|
822
|
+
throw new Error("unexpected pubkey rewardaddress for redeemer withdrawal");
|
|
823
|
+
}
|
|
824
|
+
return cred.hash;
|
|
825
|
+
}
|
|
826
|
+
else {
|
|
827
|
+
return DCert.validatorHash(redeemer.dcert);
|
|
828
|
+
}
|
|
829
|
+
};
|
|
830
|
+
const profileRedeemer = (b, tx) => (vh, redeemerIndex) => Effect.gen(function* () {
|
|
831
|
+
const script = getUplcScript(b, vh);
|
|
832
|
+
const args = yield* Uplc.ScriptContext.makeArgs(script.version, tx, redeemerIndex);
|
|
833
|
+
const costModel = yield* Network.Params.costModel(script.version);
|
|
834
|
+
const profile = yield* Uplc.Script.eval(script, args, costModel);
|
|
835
|
+
if (profile.value._tag == "Left") {
|
|
836
|
+
// TODO: return a RuntimeError with nice stack trace
|
|
837
|
+
return yield* Effect.fail(new Error(profile.value.left.error));
|
|
838
|
+
}
|
|
839
|
+
return profile.cost;
|
|
840
|
+
});
|
|
841
|
+
const updateScriptDataHash = (tx) => Effect.gen(function* () {
|
|
842
|
+
const scriptDataHash = yield* Tx.scriptDataHash(tx);
|
|
843
|
+
// assign result before returning so that return type is Tx
|
|
844
|
+
tx = {
|
|
845
|
+
...tx,
|
|
846
|
+
body: {
|
|
847
|
+
...tx.body,
|
|
848
|
+
scriptDataHash
|
|
849
|
+
}
|
|
850
|
+
};
|
|
851
|
+
return tx;
|
|
852
|
+
});
|
|
853
|
+
const updateFee = (tx) => Effect.gen(function* () {
|
|
854
|
+
const fee = yield* Tx.minFee(tx);
|
|
855
|
+
// assign result before returning so that return type is Tx
|
|
856
|
+
tx = {
|
|
857
|
+
...tx,
|
|
858
|
+
body: {
|
|
859
|
+
...tx.body,
|
|
860
|
+
fee
|
|
861
|
+
}
|
|
862
|
+
};
|
|
863
|
+
return tx;
|
|
864
|
+
});
|
|
865
|
+
const selectCoinsForBalancing = CoinSelection.smallestFirst({
|
|
866
|
+
allowSelectingUninvolvedAssets: true
|
|
867
|
+
});
|
|
868
|
+
const balanceTx = (tx, config) => Effect.gen(function* () {
|
|
869
|
+
const inputAssets = UTxO.sumAssets(...tx.body.inputs);
|
|
870
|
+
const outputAssets = Assets.sum(...tx.body.outputs.map((output) => output.assets));
|
|
871
|
+
const feeAssets = { "": tx.body.fee };
|
|
872
|
+
const mintedAssets = tx.body.minted;
|
|
873
|
+
let net = Assets.sum(inputAssets, mintedAssets, Assets.negate(outputAssets), Assets.negate(feeAssets));
|
|
874
|
+
/**
|
|
875
|
+
* Return if already balanced
|
|
876
|
+
*/
|
|
877
|
+
if (Assets.isEmpty(net)) {
|
|
878
|
+
return tx;
|
|
879
|
+
}
|
|
880
|
+
const selectAndAddInputs = (amount) => Effect.gen(function* () {
|
|
881
|
+
const extraInputs = yield* selectCoinsForBalancing(UTxO.difference(config.spareUTxOs ?? [], tx.body.inputs.concat(tx.body.refInputs)), amount);
|
|
882
|
+
net = Assets.add(net, UTxO.sumAssets(...extraInputs));
|
|
883
|
+
tx = {
|
|
884
|
+
...tx,
|
|
885
|
+
body: {
|
|
886
|
+
...tx.body,
|
|
887
|
+
inputs: UTxO.append(tx.body.inputs, ...extraInputs)
|
|
888
|
+
}
|
|
889
|
+
};
|
|
890
|
+
});
|
|
891
|
+
/**
|
|
892
|
+
* Any negative assets must be added on the input side by using the spareUTxOs
|
|
893
|
+
*/
|
|
894
|
+
if (!Assets.isEmpty(Assets.filterNegative(net))) {
|
|
895
|
+
yield* selectAndAddInputs(Assets.negate(Assets.filterNegative(net)));
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Handle the unlikely event that the tx is already balanced with the extraInputs
|
|
899
|
+
*/
|
|
900
|
+
if (Assets.isEmpty(net)) {
|
|
901
|
+
return tx;
|
|
902
|
+
}
|
|
903
|
+
if (Address.isValidator(config.changeAddress)) {
|
|
904
|
+
throw new Error("can't send change to validator");
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* Lookup or create the change output (TODO: support multiple change outputs?)
|
|
908
|
+
*/
|
|
909
|
+
let changeOutput = tx.body.outputs.find((output) => output.address == config.changeAddress &&
|
|
910
|
+
output.datum === undefined &&
|
|
911
|
+
output.refScript === undefined);
|
|
912
|
+
const nonChangeOutputs = tx.body.outputs.filter((output) => output != changeOutput);
|
|
913
|
+
/**
|
|
914
|
+
* Create the change output if no change output was found
|
|
915
|
+
*/
|
|
916
|
+
if (changeOutput === undefined) {
|
|
917
|
+
changeOutput = {
|
|
918
|
+
address: config.changeAddress,
|
|
919
|
+
assets: Assets.filterPositive(net)
|
|
920
|
+
};
|
|
921
|
+
net = {};
|
|
922
|
+
}
|
|
923
|
+
const minLovelace = yield* TxOutput.minLovelace(changeOutput);
|
|
924
|
+
let diff = minLovelace - (changeOutput.assets[""] ?? 0n);
|
|
925
|
+
while (diff > 0n) {
|
|
926
|
+
yield* selectAndAddInputs({ "": diff });
|
|
927
|
+
changeOutput = {
|
|
928
|
+
...changeOutput,
|
|
929
|
+
assets: Assets.add(changeOutput.assets, Assets.filterPositive(net))
|
|
930
|
+
};
|
|
931
|
+
net = {};
|
|
932
|
+
diff =
|
|
933
|
+
(yield* TxOutput.minLovelace(changeOutput)) -
|
|
934
|
+
(changeOutput.assets[""] ?? 0n);
|
|
935
|
+
}
|
|
936
|
+
// assign result before returning so that return type is Tx
|
|
937
|
+
tx = {
|
|
938
|
+
...tx,
|
|
939
|
+
body: {
|
|
940
|
+
...tx.body,
|
|
941
|
+
outputs: [...nonChangeOutputs, changeOutput]
|
|
942
|
+
}
|
|
943
|
+
};
|
|
944
|
+
return tx;
|
|
945
|
+
});
|
|
946
|
+
//# sourceMappingURL=TxBuilder.js.map
|