@lucid-evolution/lucid
Version:
Next-generation transaction builder for highly scalable dApps on Cardano
1,374 lines (1,346 loc) • 87.1 kB
JavaScript
// src/core.ts
import { Effect } from "effect";
import * as CML from "@anastasia-labs/cardano-multiplatform-lib-nodejs";
var makeReturn = (program) => {
return {
unsafeRun: () => Effect.runPromise(program),
safeRun: () => Effect.runPromise(Effect.either(program)),
program: () => program
};
};
// src/lucid-evolution/utils.ts
import { fromUnit, toUnit } from "@lucid-evolution/utils";
import { Data } from "@lucid-evolution/plutus";
var datumOf = async (provider, utxo, type) => {
if (!utxo.datum) {
if (!utxo.datumHash) {
throw new Error("This UTxO does not have a datum hash.");
}
utxo.datum = await provider.getDatum(utxo.datumHash);
}
return Data.from(utxo.datum, type);
};
var metadataOf = async (provider, unit) => {
const { policyId, name, label } = fromUnit(unit);
switch (label) {
case 222:
case 333:
case 444: {
const utxo = await provider.getUtxoByUnit(toUnit(policyId, name, 100));
const metadata = await datumOf(provider, utxo);
return Data.toJson(metadata.fields[0]);
}
default:
throw new Error("No variant matched.");
}
};
// src/lucid-evolution/LucidEvolution.ts
import {
createCostModels,
unixTimeToSlot as unixTimeToSlot2
} from "@lucid-evolution/utils";
// src/tx-builder/internal/Collect.ts
import { Effect as Effect4, pipe as pipe2 } from "effect";
import { Data as Data3 } from "@lucid-evolution/plutus";
import { utxoToCore } from "@lucid-evolution/utils";
// src/Errors.ts
import { Data as Data2 } from "effect";
var ERROR_MESSAGE = {
MULTIPLE_POLICIES: "MULTIPLE_POLICIES: Only one policy id allowed. You can chain multiple mintAssets functions together if you need to mint assets with different policy ids. ",
EMPTY_UTXO: "EMPTY_UTXO: UTxO array is empty. If a Tx has been recently submitted, consider waiting for chain sync",
MISSING_WALLET: "MISSING_WALLET: please ensure that your wallet has been properly configured and initialized",
MISSING_REDEEMER: "MISSING_REDEEMER: redeemer can not be undefined",
DATUM_NOT_SET: "DATUM_NOT_SET: Script inputs becomes unspendable without datum.",
EMPTY_ASSETS: "EMPTY_ASSETS: Attempting to pay to an address with an empty assets object",
MISSING_REWARD_TYPE: "MISSING_REWARD_TYPE: Address type must be Reward type.",
MISSING_STAKE_CREDENTIAL: "MISSING_STAKE_CREDENTIAL: Address does not contain stake credential",
MISSING_PAYMENT_CREDENTIAL: "MISSING_PAYMENT_CREDENTIAL: Address does not contain payment credential",
INVALID_METADATA: "INVALID_METADATA: metadata is invalid",
SCRIPT_CREDENTIAL_NOT_ALLOWED: "SCRIPT_CREDENTIAL_NOT_ALLOWED: Only verification key credential is allowed",
INVALID_SCRIPT: "INVALID_SCRIPT: Script is invalid",
EXPECTED_KEY_HASH: "EXPECTED_KEY_HASH",
INVALID_NETWORK: (address, actualNetworkId, network) => `Invalid address: ${address}, Expected address with network id ${actualNetworkId}, current network ${network}`,
MISSING_SCRIPT: (hash) => `MISSING_SCRIPT: Script not found when building transaction, consider using attach modules. script_hash: ${hash}`,
MISSING_POLICY: (policyId) => `MISSING_POLICY: No policy found, policy_id: ${policyId}`
};
var NullableError = class extends Data2.TaggedError("NullableError") {
};
var UnauthorizedNetwork = class extends Data2.TaggedError(
"UnauthorizedNetwork"
) {
};
var TxBuilderError = class extends Data2.TaggedError("TxBuilderError") {
get message() {
return `${this.cause}`;
}
};
var TxSignerError = class extends Data2.TaggedError("TxSignerError") {
get message() {
return `${this.cause}`;
}
};
var TxSubmitError = class extends Data2.TaggedError("TxSubmitError") {
get message() {
return `${this.cause}`;
}
};
var RunTimeError = class extends Data2.TaggedError("RunTimeError") {
get message() {
return `${this.cause}`;
}
};
// src/tx-builder/internal/Collect.ts
import * as CML3 from "@anastasia-labs/cardano-multiplatform-lib-nodejs";
// src/tx-builder/internal/TxUtils.ts
import * as CML2 from "@anastasia-labs/cardano-multiplatform-lib-nodejs";
import { Effect as Effect2, pipe } from "effect";
import { networkToId, getAddressDetails } from "@lucid-evolution/utils";
var txBuilderError = (cause) => new TxBuilderError({ cause: `{ TxBuilderError : ${cause} }` });
var toCMLAddress = (address, lucidConfig) => Effect2.gen(function* ($) {
const { type } = yield* validateAddressDetails(address, lucidConfig);
return type === "Byron" ? CML2.ByronAddress.from_base58(address).to_address() : CML2.Address.from_bech32(address);
});
var toV1 = (script) => CML2.PlutusScript.from_v1(CML2.PlutusV1Script.from_cbor_hex(script));
var toV2 = (script) => CML2.PlutusScript.from_v2(CML2.PlutusV2Script.from_cbor_hex(script));
var toV3 = (script) => CML2.PlutusScript.from_v3(CML2.PlutusV3Script.from_cbor_hex(script));
var toPartial = (script, redeemer) => CML2.PartialPlutusWitness.new(
CML2.PlutusScriptWitness.new_script(script),
CML2.PlutusData.from_cbor_hex(redeemer)
);
var handleRedeemerBuilder = (config, partialProgram, redeemer) => {
if (typeof redeemer === "object") {
config.partialPrograms.set(redeemer, partialProgram);
} else {
const program = partialProgram(redeemer);
config.programs.push(program);
}
};
var validateAddressDetails = (address, lucidConfig) => Effect2.gen(function* ($) {
const addressDetails = yield* $(
Effect2.try({
try: () => getAddressDetails(address),
catch: (cause) => new TxBuilderError({
cause
})
})
);
const actualNetworkId = networkToId(lucidConfig.network);
if (addressDetails.networkId !== actualNetworkId)
yield* new TxBuilderError({
cause: ERROR_MESSAGE.INVALID_NETWORK(
address,
actualNetworkId,
lucidConfig.network
)
});
return addressDetails;
});
var processCertificate = (stakeCredential, config, buildCert, redeemer) => Effect2.gen(function* () {
switch (stakeCredential.type) {
case "Key": {
const credential = CML2.Credential.new_pub_key(
CML2.Ed25519KeyHash.from_hex(stakeCredential.hash)
);
const certBuilder = buildCert(credential);
config.txBuilder.add_cert(certBuilder.payment_key());
break;
}
case "Script": {
const credential = CML2.Credential.new_script(
CML2.ScriptHash.from_hex(stakeCredential.hash)
);
const certBuilder = buildCert(credential);
const script = yield* pipe(
Effect2.fromNullable(config.scripts.get(stakeCredential.hash)),
Effect2.orElseFail(
() => txBuilderError(ERROR_MESSAGE.MISSING_SCRIPT(stakeCredential.hash))
)
);
const addPlutusCertificate = (scriptVersion) => {
return Effect2.gen(function* () {
const red = yield* pipe(
Effect2.fromNullable(redeemer),
Effect2.orElseFail(
() => txBuilderError(ERROR_MESSAGE.MISSING_REDEEMER)
)
);
config.txBuilder.add_cert(
certBuilder.plutus_script(
toPartial(scriptVersion, red),
CML2.Ed25519KeyHashList.new()
)
);
});
};
switch (script.type) {
case "PlutusV1":
yield* addPlutusCertificate(toV1(script.script));
break;
case "PlutusV2":
yield* addPlutusCertificate(toV2(script.script));
break;
case "PlutusV3":
yield* addPlutusCertificate(toV3(script.script));
break;
case "Native":
config.txBuilder.add_cert(
certBuilder.native_script(
CML2.NativeScript.from_cbor_hex(script.script),
CML2.NativeScriptWitnessInfo.assume_signature_count()
)
);
break;
}
break;
}
}
});
var validateAndGetStakeCredential = (rewardAddress, config) => Effect2.gen(function* () {
const addressDetails = yield* pipe(
validateAddressDetails(rewardAddress, config.lucidConfig),
Effect2.andThen(
(address) => address.type !== "Reward" ? txBuilderError(ERROR_MESSAGE.MISSING_REWARD_TYPE) : Effect2.succeed(address)
)
);
const stakeCredential = yield* pipe(
Effect2.fromNullable(addressDetails.stakeCredential),
Effect2.orElseFail(
() => txBuilderError(ERROR_MESSAGE.MISSING_STAKE_CREDENTIAL)
)
);
return stakeCredential;
});
var resolveDatum = (datumHash, datum, provider) => Effect2.gen(function* () {
if (!datumHash || datum) return datum;
return yield* Effect2.tryPromise({
try: () => provider.getDatum(datumHash),
catch: txBuilderError
});
});
// src/tx-builder/internal/Collect.ts
import { paymentCredentialOf } from "@lucid-evolution/utils";
// src/tx-builder/internal/Service.ts
import { Context } from "effect";
var TxConfig = class extends Context.Tag("TxConfig")() {
};
// src/tx-builder/internal/Collect.ts
var collectError = (cause) => new TxBuilderError({ cause: `{ Collect: ${cause} }` });
var collectFromUTxO = (utxos, collectInputs = true) => (redeemer) => Effect4.gen(function* () {
const { config } = yield* TxConfig;
if (utxos.length === 0) yield* collectError(ERROR_MESSAGE.EMPTY_UTXO);
for (const utxo of utxos) {
const resolvedDatum = yield* resolveDatum(
utxo.datumHash,
utxo.datum,
config.lucidConfig.provider
);
utxo.datum = resolvedDatum;
if (collectInputs) config.collectedInputs.push(utxo);
const input = CML3.SingleInputBuilder.from_transaction_unspent_output(
utxoToCore({ ...utxo, datum: resolvedDatum })
);
const credential = paymentCredentialOf(utxo.address);
if (credential.type == "Script") {
const script = yield* pipe2(
Effect4.fromNullable(config.scripts.get(credential.hash)),
Effect4.orElseFail(
() => collectError(
collectError(ERROR_MESSAGE.MISSING_SCRIPT(credential.hash))
)
)
);
switch (script.type) {
case "Native":
config.txBuilder.add_input(
input.native_script(
CML3.NativeScript.from_cbor_hex(script.script),
CML3.NativeScriptWitnessInfo.assume_signature_count()
)
);
break;
case "PlutusV1": {
const red = yield* pipe2(
Effect4.fromNullable(redeemer),
Effect4.orElseFail(
() => collectError(ERROR_MESSAGE.MISSING_REDEEMER)
)
);
config.txBuilder.add_input(
input.plutus_script(
toPartial(toV1(script.script), red),
CML3.Ed25519KeyHashList.new(),
CML3.PlutusData.from_cbor_hex(utxo.datum)
)
);
break;
}
case "PlutusV2": {
const v2 = toV2(script.script);
const red = yield* pipe2(
Effect4.fromNullable(redeemer),
Effect4.orElseFail(
() => collectError(ERROR_MESSAGE.MISSING_REDEEMER)
)
);
const partial = toPartial(v2, red);
config.txBuilder.add_input(
utxo.datum && utxo.datumHash ? input.plutus_script(
partial,
CML3.Ed25519KeyHashList.new(),
CML3.PlutusData.from_cbor_hex(utxo.datum)
) : input.plutus_script_inline_datum(
partial,
CML3.Ed25519KeyHashList.new()
)
);
break;
}
case "PlutusV3": {
const v3 = toV3(script.script);
const red = yield* pipe2(
Effect4.fromNullable(redeemer),
Effect4.orElseFail(
() => collectError(ERROR_MESSAGE.MISSING_REDEEMER)
)
);
const partial = toPartial(v3, red);
config.txBuilder.add_input(
utxo.datum && utxo.datumHash ? input.plutus_script(
partial,
CML3.Ed25519KeyHashList.new(),
CML3.PlutusData.from_cbor_hex(utxo.datum)
) : input.plutus_script_inline_datum(
partial,
CML3.Ed25519KeyHashList.new()
)
);
break;
}
}
} else {
config.txBuilder.add_input(input.payment_key());
}
}
});
var collectFromUTxOPartial = (utxos, redeemerBuilder) => Effect4.gen(function* () {
const { config } = yield* TxConfig;
if (utxos.length === 0) yield* collectError(ERROR_MESSAGE.EMPTY_UTXO);
if (redeemerBuilder.kind === "self") redeemerBuilder.inputs = utxos;
for (const utxo of utxos) {
if (utxo.datumHash && !utxo.datum) {
const data = yield* Effect4.tryPromise({
try: () => datumOf(config.lucidConfig.provider, utxo),
catch: (cause) => collectError({ cause })
});
utxo.datum = Data3.to(data);
}
config.collectedInputs.push(utxo);
}
const partialProgram = collectFromUTxO(utxos, false);
config.partialPrograms.set(redeemerBuilder, partialProgram);
});
// src/tx-builder/internal/Read.ts
import { Effect as Effect5 } from "effect";
import { utxoToCore as utxoToCore2 } from "@lucid-evolution/utils";
var readError = (cause) => new TxBuilderError({ cause: `{ Read : ${cause} }` });
var readFrom = (utxos) => Effect5.gen(function* () {
const { config } = yield* TxConfig;
if (utxos.length === 0) yield* readError(ERROR_MESSAGE.EMPTY_UTXO);
for (const utxo of utxos) {
const resolvedDatum = yield* resolveDatum(
utxo.datumHash,
utxo.datum,
config.lucidConfig.provider
);
const coreUtxo = utxoToCore2({ ...utxo, datum: resolvedDatum });
const exists = config.readInputs.some(
(input) => input.txHash === utxo.txHash && input.outputIndex === utxo.outputIndex
);
if (!exists) {
config.txBuilder.add_reference_input(coreUtxo);
config.readInputs.push(utxo);
}
}
});
// src/tx-builder/internal/Attach.ts
import { applyDoubleCborEncoding } from "@lucid-evolution/utils";
var attachScript = ({ type, script }) => {
switch (type) {
case "Native":
return {
key: CML.NativeScript.from_cbor_hex(script).hash().to_hex(),
value: { type, script }
};
case "PlutusV1":
return {
key: CML.PlutusV1Script.from_cbor_hex(applyDoubleCborEncoding(script)).hash().to_hex(),
value: { type, script: applyDoubleCborEncoding(script) }
};
case "PlutusV2":
return {
key: CML.PlutusV2Script.from_cbor_hex(applyDoubleCborEncoding(script)).hash().to_hex(),
value: { type, script: applyDoubleCborEncoding(script) }
};
case "PlutusV3":
return {
key: CML.PlutusV3Script.from_cbor_hex(applyDoubleCborEncoding(script)).hash().to_hex(),
value: { type, script: applyDoubleCborEncoding(script) }
};
default:
throw new Error(`Exhaustive check failed: Unhandled case ${type}`);
}
};
var attachSpendingValidator = (spendingValidator) => attachScript(spendingValidator);
var attachMintingPolicy = (mintingPolicy) => attachScript(mintingPolicy);
var attachCertificateValidator = (certValidator) => attachScript(certValidator);
var attachWithdrawalValidator = (withdrawalValidator) => attachScript(withdrawalValidator);
var attachVoteValidator = (voteValidator) => attachScript(voteValidator);
var attachProposeValidator = (proposeValidator) => attachScript(proposeValidator);
// src/tx-builder/internal/Pay.ts
import { Effect as Effect6 } from "effect";
import {
addAssets,
assetsToValue,
coreToTxOutput,
toScriptRef,
valueToAssets
} from "@lucid-evolution/utils";
var payError = (cause) => new TxBuilderError({ cause: `{ Pay: ${cause} }` });
var payToAddress = (address, assets) => Effect6.gen(function* () {
const { config } = yield* TxConfig;
const outputBuilder = CML.TransactionOutputBuilder.new().with_address(yield* toCMLAddress(address, config.lucidConfig)).next();
if (Object.keys(assets).length == 0)
yield* payError(ERROR_MESSAGE.EMPTY_ASSETS);
const value = assetsToValue(assets);
let outputResult = outputBuilder.with_asset_and_min_required_coin(
value.multi_asset(),
config.lucidConfig.protocolParameters.coinsPerUtxoByte
).build();
const setLovelaces = assets["lovelace"];
if (setLovelaces) {
const minLovelace = outputResult.output().amount().coin();
if (setLovelaces > minLovelace) {
outputResult = outputBuilder.with_value(value).build();
}
}
config.totalOutputAssets = addAssets(
config.totalOutputAssets,
valueToAssets(outputResult.output().amount())
);
config.payToOutputs = [
...config.payToOutputs,
coreToTxOutput(outputResult.output())
];
config.txBuilder.add_output(outputResult);
});
var ToAddressWithData = (address, outputDatum, assets, scriptRef) => Effect6.gen(function* () {
const { config } = yield* TxConfig;
const outputBuilder = buildBaseOutput(address, outputDatum, scriptRef);
assets ??= {};
const value = assetsToValue(assets);
let outputResult = outputBuilder.with_asset_and_min_required_coin(
value.multi_asset(),
config.lucidConfig.protocolParameters.coinsPerUtxoByte
).build();
const setLovelaces = assets["lovelace"];
if (setLovelaces) {
const minLovelace = outputResult.output().amount().coin();
if (setLovelaces > minLovelace) {
outputResult = outputBuilder.with_value(value).build();
}
}
config.totalOutputAssets = addAssets(
config.totalOutputAssets,
valueToAssets(outputResult.output().amount())
);
config.payToOutputs = [
...config.payToOutputs,
coreToTxOutput(outputResult.output())
];
config.txBuilder.add_output(outputResult);
});
var ToContract = (address, outputDatum, assets, scriptRef) => ToAddressWithData(address, outputDatum, assets, scriptRef);
var buildBaseOutput = (address, outputDatum, scriptRef) => {
let baseBuilder;
const addressBuilder = CML.TransactionOutputBuilder.new().with_address(
CML.Address.from_bech32(address)
);
if (outputDatum) {
if (outputDatum.value.trim() === "") {
throw new Error(
"datum value is missing. Please provide a non-empty cbor hex data."
);
}
switch (outputDatum.kind) {
case "hash": {
const datumOption = CML.DatumOption.new_hash(
CML.DatumHash.from_hex(outputDatum.value)
);
baseBuilder = addressBuilder.with_data(datumOption);
break;
}
case "asHash": {
const plutusData = CML.PlutusData.from_cbor_hex(outputDatum.value);
baseBuilder = addressBuilder.with_communication_data(plutusData);
break;
}
case "inline": {
const plutusData = CML.PlutusData.from_cbor_hex(outputDatum.value);
const datumOption = CML.DatumOption.new_datum(plutusData);
baseBuilder = addressBuilder.with_data(datumOption);
break;
}
default:
throw new Error(`Unknown outputDatum: ${outputDatum}`);
}
} else {
baseBuilder = addressBuilder;
}
return scriptRef ? baseBuilder.with_reference_script(toScriptRef(scriptRef)).next() : baseBuilder.next();
};
// src/tx-builder/internal/Mint.ts
import { Effect as Effect7, pipe as pipe3 } from "effect";
import * as CML4 from "@anastasia-labs/cardano-multiplatform-lib-nodejs";
var mintError = (cause) => new TxBuilderError({ cause: `{ Mint: ${cause} }` });
var mintAssets = (assets) => (redeemer) => Effect7.gen(function* () {
const { config } = yield* TxConfig;
const units = Object.keys(assets);
const policyId = units[0].slice(0, 56);
const mintAssets2 = CML4.MapAssetNameToNonZeroInt64.new();
for (const unit of units) {
if (unit.slice(0, 56) !== policyId) {
yield* mintError(ERROR_MESSAGE.MULTIPLE_POLICIES);
}
mintAssets2.insert(CML4.AssetName.from_hex(unit.slice(56)), assets[unit]);
}
const mintBuilder = CML4.SingleMintBuilder.new(mintAssets2);
const policy = yield* pipe3(
Effect7.fromNullable(config.scripts.get(policyId)),
Effect7.orElseFail(
() => mintError(ERROR_MESSAGE.MISSING_POLICY(policyId))
)
);
switch (policy.type) {
case "Native":
config.txBuilder.add_mint(
mintBuilder.native_script(
CML4.NativeScript.from_cbor_hex(policy.script),
CML4.NativeScriptWitnessInfo.assume_signature_count()
)
);
break;
case "PlutusV1": {
const red = yield* pipe3(
Effect7.fromNullable(redeemer),
Effect7.orElseFail(() => mintError(ERROR_MESSAGE.MISSING_REDEEMER))
);
config.txBuilder.add_mint(
mintBuilder.plutus_script(
toPartial(toV1(policy.script), red),
CML4.Ed25519KeyHashList.new()
)
);
break;
}
case "PlutusV2": {
const red = yield* pipe3(
Effect7.fromNullable(redeemer),
Effect7.orElseFail(() => mintError(ERROR_MESSAGE.MISSING_REDEEMER))
);
config.txBuilder.add_mint(
mintBuilder.plutus_script(
toPartial(toV2(policy.script), red),
CML4.Ed25519KeyHashList.new()
)
);
break;
}
case "PlutusV3": {
const red = yield* pipe3(
Effect7.fromNullable(redeemer),
Effect7.orElseFail(() => mintError(ERROR_MESSAGE.MISSING_REDEEMER))
);
config.txBuilder.add_mint(
mintBuilder.plutus_script(
toPartial(toV3(policy.script), red),
CML4.Ed25519KeyHashList.new()
)
);
break;
}
}
});
// src/tx-builder/internal/Interval.ts
import { Effect as Effect8 } from "effect";
import { unixTimeToSlot } from "@lucid-evolution/utils";
var validFrom = (unixTime) => Effect8.gen(function* () {
const { config } = yield* TxConfig;
const slot = unixTimeToSlot(config.lucidConfig.network, unixTime);
config.txBuilder.set_validity_start_interval(BigInt(slot));
});
var validTo = (unixTime) => Effect8.gen(function* () {
const { config } = yield* TxConfig;
const slot = unixTimeToSlot(config.lucidConfig.network, unixTime);
config.txBuilder.set_ttl(BigInt(slot));
});
// src/tx-builder/internal/Signer.ts
import { Effect as Effect9, pipe as pipe4 } from "effect";
import * as CML5 from "@anastasia-labs/cardano-multiplatform-lib-nodejs";
var addSignerError = (cause) => new TxBuilderError({ cause: `{ Signer: ${cause} }` });
var addSigner = (address) => Effect9.gen(function* () {
const { config } = yield* TxConfig;
const addressDetails = yield* validateAddressDetails(
address,
config.lucidConfig
);
const credential = addressDetails.type === "Reward" ? yield* pipe4(
Effect9.fromNullable(addressDetails.stakeCredential),
Effect9.orElseFail(
() => addSignerError(ERROR_MESSAGE.MISSING_STAKE_CREDENTIAL)
)
) : yield* pipe4(
Effect9.fromNullable(addressDetails.paymentCredential),
Effect9.orElseFail(
() => addSignerError(ERROR_MESSAGE.MISSING_PAYMENT_CREDENTIAL)
)
);
if (credential.type === "Script")
yield* addSignerError(ERROR_MESSAGE.SCRIPT_CREDENTIAL_NOT_ALLOWED);
return credential.hash;
}).pipe(Effect9.flatMap((keyHash) => addSignerKey(keyHash)));
var addSignerKey = (keyHash) => Effect9.gen(function* () {
const { config } = yield* TxConfig;
config.txBuilder.add_required_signer(CML5.Ed25519KeyHash.from_hex(keyHash));
});
// src/tx-builder/internal/Stake.ts
import { Effect as Effect10, pipe as pipe5 } from "effect";
import * as CML6 from "@anastasia-labs/cardano-multiplatform-lib-nodejs";
var stakeError = (cause) => new TxBuilderError({ cause: `{ Stake: ${cause} }` });
var registerStake = (rewardAddress) => Effect10.gen(function* () {
const { config } = yield* TxConfig;
const addressDetails = yield* pipe5(
validateAddressDetails(rewardAddress, config.lucidConfig),
Effect10.andThen(
(address) => address.type !== "Reward" ? stakeError(ERROR_MESSAGE.MISSING_REWARD_TYPE) : Effect10.succeed(address)
)
);
const stakeCredential = yield* pipe5(
Effect10.fromNullable(addressDetails.stakeCredential),
Effect10.orElseFail(
() => stakeError(ERROR_MESSAGE.MISSING_STAKE_CREDENTIAL)
)
);
const credential = stakeCredential.type === "Key" ? CML6.Credential.new_pub_key(
CML6.Ed25519KeyHash.from_hex(stakeCredential.hash)
) : CML6.Credential.new_script(
CML6.ScriptHash.from_hex(stakeCredential.hash)
);
const certBuilder = CML6.SingleCertificateBuilder.new(
CML6.Certificate.new_stake_registration(credential)
);
config.txBuilder.add_cert(certBuilder.skip_witness());
});
var deRegisterStake = (rewardAddress, redeemer) => Effect10.gen(function* () {
const { config } = yield* TxConfig;
const addressDetails = yield* pipe5(
validateAddressDetails(rewardAddress, config.lucidConfig),
Effect10.andThen(
(address) => address.type !== "Reward" ? stakeError(ERROR_MESSAGE.MISSING_REWARD_TYPE) : Effect10.succeed(address)
)
);
const stakeCredential = yield* pipe5(
Effect10.fromNullable(addressDetails.stakeCredential),
Effect10.orElseFail(
() => stakeError(ERROR_MESSAGE.MISSING_STAKE_CREDENTIAL)
)
);
const createCertBuilder = (credential, config2) => {
return CML6.SingleCertificateBuilder.new(
CML6.Certificate.new_unreg_cert(
credential,
config2.lucidConfig.protocolParameters.keyDeposit
)
);
};
switch (stakeCredential.type) {
case "Key": {
const credential = CML6.Credential.new_pub_key(
CML6.Ed25519KeyHash.from_hex(stakeCredential.hash)
);
const certBuilder = createCertBuilder(credential, config);
config.txBuilder.add_cert(certBuilder.payment_key());
break;
}
case "Script": {
const credential = CML6.Credential.new_script(
CML6.ScriptHash.from_hex(stakeCredential.hash)
);
const certBuilder = createCertBuilder(credential, config);
const script = yield* pipe5(
Effect10.fromNullable(config.scripts.get(stakeCredential.hash)),
Effect10.orElseFail(
() => stakeError(ERROR_MESSAGE.MISSING_SCRIPT(stakeCredential.hash))
)
);
const handleRedeemer = () => pipe5(
Effect10.fromNullable(redeemer),
Effect10.orElseFail(() => stakeError(ERROR_MESSAGE.MISSING_REDEEMER))
);
switch (script.type) {
case "PlutusV1": {
const red = yield* handleRedeemer();
config.txBuilder.add_cert(
certBuilder.plutus_script(
toPartial(toV1(script.script), red),
CML6.Ed25519KeyHashList.new()
)
);
break;
}
case "PlutusV2": {
const red = yield* handleRedeemer();
config.txBuilder.add_cert(
certBuilder.plutus_script(
toPartial(toV2(script.script), red),
CML6.Ed25519KeyHashList.new()
)
);
break;
}
case "PlutusV3": {
const red = yield* handleRedeemer();
config.txBuilder.add_cert(
certBuilder.plutus_script(
toPartial(toV3(script.script), red),
CML6.Ed25519KeyHashList.new()
)
);
break;
}
case "Native": {
config.txBuilder.add_cert(
certBuilder.native_script(
CML6.NativeScript.from_cbor_hex(script.script),
CML6.NativeScriptWitnessInfo.assume_signature_count()
)
);
break;
}
}
}
}
});
var withdraw = (rewardAddress, amount) => (redeemer) => Effect10.gen(function* () {
const { config } = yield* TxConfig;
const addressDetails = yield* pipe5(
validateAddressDetails(rewardAddress, config.lucidConfig),
Effect10.andThen(
(address) => address.type !== "Reward" ? stakeError(ERROR_MESSAGE.MISSING_REWARD_TYPE) : Effect10.succeed(address)
)
);
const withdrawBuilder = yield* pipe5(
Effect10.fromNullable(
CML6.RewardAddress.from_address(
CML6.Address.from_bech32(rewardAddress)
)
),
Effect10.orElseFail(
() => stakeError(ERROR_MESSAGE.MISSING_STAKE_CREDENTIAL)
),
Effect10.andThen(
(address) => CML6.SingleWithdrawalBuilder.new(address, amount)
)
);
const stakeCredential = yield* pipe5(
Effect10.fromNullable(addressDetails.stakeCredential),
Effect10.orElseFail(
() => stakeError(ERROR_MESSAGE.MISSING_STAKE_CREDENTIAL)
)
);
const handleRedeemer = () => pipe5(
Effect10.fromNullable(redeemer),
Effect10.orElseFail(() => stakeError(ERROR_MESSAGE.MISSING_REDEEMER))
);
switch (stakeCredential.type) {
case "Key": {
config.txBuilder.add_withdrawal(withdrawBuilder.payment_key());
break;
}
case "Script": {
const script = yield* pipe5(
Effect10.fromNullable(config.scripts.get(stakeCredential.hash)),
Effect10.orElseFail(
() => stakeError(ERROR_MESSAGE.MISSING_SCRIPT(stakeCredential.hash))
)
);
switch (script.type) {
case "PlutusV1": {
const red = yield* handleRedeemer();
config.txBuilder.add_withdrawal(
withdrawBuilder.plutus_script(
toPartial(toV1(script.script), red),
CML6.Ed25519KeyHashList.new()
)
);
break;
}
case "PlutusV2": {
const red = yield* handleRedeemer();
config.txBuilder.add_withdrawal(
withdrawBuilder.plutus_script(
toPartial(toV2(script.script), red),
CML6.Ed25519KeyHashList.new()
)
);
break;
}
case "PlutusV3": {
const red = yield* handleRedeemer();
config.txBuilder.add_withdrawal(
withdrawBuilder.plutus_script(
toPartial(toV3(script.script), red),
CML6.Ed25519KeyHashList.new()
)
);
break;
}
case "Native": {
config.txBuilder.add_withdrawal(
withdrawBuilder.native_script(
CML6.NativeScript.from_cbor_hex(script.script),
CML6.NativeScriptWitnessInfo.assume_signature_count()
)
);
break;
}
}
}
}
});
// src/tx-builder/internal/Pool.ts
import { Effect as Effect11, pipe as pipe6 } from "effect";
import * as CML7 from "@anastasia-labs/cardano-multiplatform-lib-nodejs";
import { fromText } from "@lucid-evolution/core-utils";
var poolError = (cause) => new TxBuilderError({ cause: `{ Pool : ${cause} }` });
var delegateTo = (rewardAddress, poolId, redeemer) => Effect11.gen(function* () {
const { config } = yield* TxConfig;
const addressDetails = yield* pipe6(
validateAddressDetails(rewardAddress, config.lucidConfig),
Effect11.andThen(
(address) => address.type !== "Reward" ? poolError(ERROR_MESSAGE.MISSING_REWARD_TYPE) : Effect11.succeed(address)
)
);
const stakeCredential = yield* pipe6(
Effect11.fromNullable(addressDetails.stakeCredential),
Effect11.orElseFail(
() => poolError(ERROR_MESSAGE.MISSING_STAKE_CREDENTIAL)
)
);
switch (stakeCredential.type) {
case "Key": {
const credential = CML7.Credential.new_pub_key(
CML7.Ed25519KeyHash.from_hex(stakeCredential.hash)
);
const certBuilder = CML7.SingleCertificateBuilder.new(
CML7.Certificate.new_stake_delegation(
credential,
CML7.Ed25519KeyHash.from_bech32(poolId)
)
);
config.txBuilder.add_cert(certBuilder.payment_key());
break;
}
case "Script": {
const credential = CML7.Credential.new_script(
CML7.ScriptHash.from_hex(stakeCredential.hash)
);
const certBuilder = CML7.SingleCertificateBuilder.new(
CML7.Certificate.new_stake_delegation(
credential,
CML7.Ed25519KeyHash.from_bech32(poolId)
)
);
const script = yield* pipe6(
Effect11.fromNullable(config.scripts.get(stakeCredential.hash)),
Effect11.orElseFail(
() => poolError(ERROR_MESSAGE.MISSING_SCRIPT(stakeCredential.hash))
)
);
const handleRedeemer = () => pipe6(
Effect11.fromNullable(redeemer),
Effect11.orElseFail(() => poolError(ERROR_MESSAGE.MISSING_REDEEMER))
);
switch (script.type) {
case "PlutusV1": {
const red = yield* handleRedeemer();
config.txBuilder.add_cert(
certBuilder.plutus_script(
toPartial(toV1(script.script), red),
CML7.Ed25519KeyHashList.new()
)
);
break;
}
case "PlutusV2": {
const red = yield* handleRedeemer();
config.txBuilder.add_cert(
certBuilder.plutus_script(
toPartial(toV2(script.script), red),
CML7.Ed25519KeyHashList.new()
)
);
break;
}
case "PlutusV3": {
const red = yield* handleRedeemer();
config.txBuilder.add_cert(
certBuilder.plutus_script(
toPartial(toV3(script.script), red),
CML7.Ed25519KeyHashList.new()
)
);
break;
}
case "Native": {
config.txBuilder.add_cert(
certBuilder.native_script(
CML7.NativeScript.from_cbor_hex(script.script),
CML7.NativeScriptWitnessInfo.assume_signature_count()
)
);
break;
}
}
}
}
});
// src/tx-builder/internal/Governance.ts
import * as CML8 from "@anastasia-labs/cardano-multiplatform-lib-nodejs";
import { Effect as Effect12 } from "effect";
var isDRepCredential = (deleg) => !("__typename" in deleg);
var isDRepAlwaysAbstain = (deleg) => !isDRepCredential(deleg) && deleg.__typename === "AlwaysAbstain";
var isDRepAlwaysNoConfidence = (deleg) => !isDRepCredential(deleg) && deleg.__typename === "AlwaysNoConfidence";
var toCMLDRep = (drep) => {
if (isDRepAlwaysAbstain(drep)) {
return CML8.DRep.new_always_abstain();
} else if (isDRepAlwaysNoConfidence(drep)) {
return CML8.DRep.new_always_no_confidence();
} else if (isDRepCredential(drep)) {
switch (drep.type) {
case "Key":
return CML8.DRep.new_key(CML8.Ed25519KeyHash.from_hex(drep.hash));
case "Script":
return CML8.DRep.new_script(CML8.ScriptHash.from_hex(drep.hash));
default:
throw new Error(`Unsupported DRep type: ${drep.type}`);
}
}
throw new Error(`Unexpected DRep type: ${drep}`);
};
var delegateVoteToDRep = (rewardAddress, drep, redeemer) => Effect12.gen(function* () {
const { config } = yield* TxConfig;
const stakeCredential = yield* validateAndGetStakeCredential(
rewardAddress,
config
);
const cmlDRep = toCMLDRep(drep);
const buildCert = (credential) => CML8.SingleCertificateBuilder.new(
CML8.Certificate.new_vote_deleg_cert(credential, cmlDRep)
);
yield* processCertificate(stakeCredential, config, buildCert, redeemer);
});
var delegateVoteToPoolAndDRep = (rewardAddress, poolId, drep, redeemer) => Effect12.gen(function* () {
const { config } = yield* TxConfig;
const stakeCredential = yield* validateAndGetStakeCredential(
rewardAddress,
config
);
const cmlDRep = toCMLDRep(drep);
const buildCert = (credential) => CML8.SingleCertificateBuilder.new(
CML8.Certificate.new_stake_vote_deleg_cert(
credential,
CML8.Ed25519KeyHash.from_bech32(poolId),
cmlDRep
)
);
yield* processCertificate(stakeCredential, config, buildCert, redeemer);
});
var registerAndDelegateToPool = (rewardAddress, poolId, redeemer) => Effect12.gen(function* () {
const { config } = yield* TxConfig;
const stakeCredential = yield* validateAndGetStakeCredential(
rewardAddress,
config
);
const buildCert = (credential) => CML8.SingleCertificateBuilder.new(
CML8.Certificate.new_stake_reg_deleg_cert(
credential,
CML8.Ed25519KeyHash.from_bech32(poolId),
config.lucidConfig.protocolParameters.keyDeposit
)
);
yield* processCertificate(stakeCredential, config, buildCert, redeemer);
});
var registerAndDelegateToDRep = (rewardAddress, drep, redeemer) => Effect12.gen(function* () {
const { config } = yield* TxConfig;
const stakeCredential = yield* validateAndGetStakeCredential(
rewardAddress,
config
);
const cmlDRep = toCMLDRep(drep);
const buildCert = (credential) => CML8.SingleCertificateBuilder.new(
CML8.Certificate.new_vote_reg_deleg_cert(
credential,
cmlDRep,
config.lucidConfig.protocolParameters.keyDeposit
)
);
yield* processCertificate(stakeCredential, config, buildCert, redeemer);
});
var registerAndDelegateToPoolAndDRep = (rewardAddress, poolId, drep, redeemer) => Effect12.gen(function* () {
const { config } = yield* TxConfig;
const stakeCredential = yield* validateAndGetStakeCredential(
rewardAddress,
config
);
const cmlDRep = toCMLDRep(drep);
const buildCert = (credential) => CML8.SingleCertificateBuilder.new(
CML8.Certificate.new_stake_vote_reg_deleg_cert(
credential,
CML8.Ed25519KeyHash.from_bech32(poolId),
cmlDRep,
config.lucidConfig.protocolParameters.keyDeposit
)
);
yield* processCertificate(stakeCredential, config, buildCert, redeemer);
});
var registerDRep = (rewardAddress, anchor, redeemer) => Effect12.gen(function* () {
const { config } = yield* TxConfig;
const stakeCredential = yield* validateAndGetStakeCredential(
rewardAddress,
config
);
const cmlAnchor = anchor ? CML8.Anchor.new(
CML8.Url.from_json(anchor.url),
CML8.AnchorDocHash.from_hex(anchor.dataHash)
) : void 0;
const buildCert = (credential) => CML8.SingleCertificateBuilder.new(
CML8.Certificate.new_reg_drep_cert(
credential,
config.lucidConfig.protocolParameters.drepDeposit,
cmlAnchor
)
);
yield* processCertificate(stakeCredential, config, buildCert, redeemer);
});
var deregisterDRep = (rewardAddress, redeemer) => Effect12.gen(function* () {
const { config } = yield* TxConfig;
const stakeCredential = yield* validateAndGetStakeCredential(
rewardAddress,
config
);
const buildCert = (credential) => CML8.SingleCertificateBuilder.new(
CML8.Certificate.new_unreg_drep_cert(
credential,
config.lucidConfig.protocolParameters.drepDeposit
)
);
yield* processCertificate(stakeCredential, config, buildCert, redeemer);
});
var updateDRep = (rewardAddress, anchor, redeemer) => Effect12.gen(function* () {
const { config } = yield* TxConfig;
const stakeCredential = yield* validateAndGetStakeCredential(
rewardAddress,
config
);
const cmlAnchor = anchor ? CML8.Anchor.new(
CML8.Url.from_json(anchor.url),
CML8.AnchorDocHash.from_hex(anchor.dataHash)
) : void 0;
const buildCert = (credential) => CML8.SingleCertificateBuilder.new(
CML8.Certificate.new_update_drep_cert(credential, cmlAnchor)
);
yield* processCertificate(stakeCredential, config, buildCert, redeemer);
});
var authCommitteeHot = (coldAddress, hotAddress, redeemer) => Effect12.gen(function* () {
const { config } = yield* TxConfig;
const coldCred = yield* validateAndGetStakeCredential(coldAddress, config);
const hotCred = yield* validateAndGetStakeCredential(hotAddress, config);
const hotCredential = hotCred.type === "Key" ? CML8.Credential.new_pub_key(CML8.Ed25519KeyHash.from_hex(hotCred.hash)) : CML8.Credential.new_script(CML8.ScriptHash.from_hex(hotCred.hash));
const buildCert = (credential) => CML8.SingleCertificateBuilder.new(
CML8.Certificate.new_auth_committee_hot_cert(credential, hotCredential)
);
yield* processCertificate(coldCred, config, buildCert, redeemer);
});
var resignCommitteeHot = (coldAddress, anchor, redeemer) => Effect12.gen(function* () {
const { config } = yield* TxConfig;
const coldCred = yield* validateAndGetStakeCredential(coldAddress, config);
const cmlAnchor = anchor ? CML8.Anchor.new(
CML8.Url.from_json(anchor.url),
CML8.AnchorDocHash.from_hex(anchor.dataHash)
) : void 0;
const buildCert = (credential) => CML8.SingleCertificateBuilder.new(
CML8.Certificate.new_resign_committee_cold_cert(credential, cmlAnchor)
);
yield* processCertificate(coldCred, config, buildCert, redeemer);
});
// src/tx-builder/internal/Metadata.ts
import { Effect as Effect13 } from "effect";
import * as S from "@effect/schema/Schema";
import { toHex } from "@lucid-evolution/core-utils";
var attachMetadata = (config, label, metadata) => Effect13.gen(function* () {
const auxiliaryData = CML.AuxiliaryData.new();
const meta = CML.Metadata.new();
meta.set(
BigInt(label),
CML.TransactionMetadatum.from_json(
JSON.stringify(toCardanoMetadata(metadata))
)
);
auxiliaryData.add_metadata(meta);
config.txBuilder.add_auxiliary_data(auxiliaryData);
auxiliaryData.free();
meta.free();
});
var TextSchema = S.String.pipe(S.maxLength(64));
var TransactionMetadataSchema = S.Union(
TextSchema,
S.Number,
S.Uint8ArrayFromSelf,
S.Array(S.suspend(() => TransactionMetadataSchema)),
S.Record(
S.String,
S.suspend(() => TransactionMetadataSchema)
)
);
var toCardanoMetadata = (json) => {
const d = S.asserts(TransactionMetadataSchema)(json);
if (S.is(TextSchema)(json)) {
return { string: json };
}
if (typeof json === "number") {
return { int: json };
}
if (json instanceof Uint8Array) {
return { bytes: toHex(json) };
}
if (Array.isArray(json)) {
return { list: json.map((value) => toCardanoMetadata(value)) };
}
if (typeof json === "object" && json !== null) {
const mapEntries = Object.entries(json).map(([k, v]) => ({
k: toCardanoMetadata(k),
v: toCardanoMetadata(v)
}));
return { map: mapEntries };
}
throw new Error("Unsupported type");
};
// src/tx-builder/internal/CompleteTxBuilder.ts
import {
Effect as Effect17,
pipe as pipe9,
Record as Record2,
Array as _Array,
BigInt as _BigInt,
Tuple,
Option
} from "effect";
import * as UPLC from "@lucid-evolution/uplc";
// src/tx-sign-builder/TxSignBuilder.ts
import * as S3 from "@effect/schema/Schema";
// src/tx-sign-builder/internal/CompleteTxSigner.ts
import { Effect as Effect16, pipe as pipe8 } from "effect";
// src/tx-submit/TxSubmit.ts
import { Effect as Effect14 } from "effect";
import * as S2 from "@effect/schema/Schema";
var makeSubmit = (wallet, txSigned) => {
const submit = (options) => Effect14.tryPromise({
try: () => wallet.submitTx(
options.canonical ? txSigned.to_canonical_cbor_hex() : txSigned.to_cbor_hex()
),
catch: (cause) => new TxSubmitError({ cause })
});
return {
submit: (options = { canonical: false }) => makeReturn(submit(options)).unsafeRun(),
submitProgram: (options = { canonical: false }) => submit(options),
submitSafe: (options = { canonical: false }) => makeReturn(submit(options)).safeRun(),
toCBOR: (options = { canonical: false }) => options.canonical ? txSigned.to_canonical_cbor_hex() : txSigned.to_cbor_hex(),
toTransaction: () => txSigned,
toJSON: () => S2.decodeUnknownSync(S2.parseJson(S2.Object))(txSigned.to_json()),
toHash: () => CML.hash_transaction(txSigned.body()).to_hex()
};
};
// src/tx-sign-builder/internal/Sign.ts
import { Effect as Effect15, pipe as pipe7 } from "effect";
var signError = (cause) => new TxSignerError({ cause });
var mkWitnessFromWallet = (wallet, txComplete) => pipe7(
Effect15.fromNullable(wallet),
Effect15.catchAll(() => signError(ERROR_MESSAGE.MISSING_WALLET)),
Effect15.tryMapPromise({
try: (wallet2) => wallet2.signTx(txComplete),
catch: (cause) => signError(cause)
})
);
var withWallet = (config) => pipe7(
mkWitnessFromWallet(config.wallet, config.txComplete),
Effect15.map((witness) => config.witnessSetBuilder.add_existing(witness))
);
var partialWithWallet = (config) => pipe7(
mkWitnessFromWallet(config.wallet, config.txComplete),
Effect15.map((witness) => witness.to_cbor_hex())
);
var mkWitnessFromPrivateKey = (privateKey, txComplete) => pipe7(
Effect15.try({
try: () => CML.PrivateKey.from_bech32(privateKey),
catch: signError
}),
Effect15.map(
(privateKey2) => CML.make_vkey_witness(
CML.hash_transaction(txComplete.body()),
privateKey2
)
)
);
var withPrivateKey = (config, privateKey) => pipe7(
mkWitnessFromPrivateKey(privateKey, config.txComplete),
Effect15.map((witness) => config.witnessSetBuilder.add_vkey(witness))
);
var partialWithPrivateKey = (config, privateKey) => pipe7(
mkWitnessFromPrivateKey(privateKey, config.txComplete),
Effect15.map((witness) => {
const witnessBuilder = CML.TransactionWitnessSetBuilder.new();
witnessBuilder.add_vkey(witness);
return witnessBuilder.build().to_cbor_hex();
})
);
var assemble = (config, witnesses) => Effect15.forEach(
witnesses,
(witness) => pipe7(
Effect15.try({
try: () => CML.TransactionWitnessSet.from_cbor_hex(witness),
catch: signError
}),
Effect15.map((witness2) => config.witnessSetBuilder.add_existing(witness2))
)
);
// src/tx-sign-builder/internal/CompleteTxSigner.ts
var completeTxSigner = (config) => Effect16.gen(function* () {
yield* Effect16.all(config.programs, { concurrency: "unbounded" });
const plutus_datums = config.txComplete.witness_set().plutus_datums();
config.witnessSetBuilder.add_existing(config.txComplete.witness_set());
if (plutus_datums) {
for (let i = 0; i < plutus_datums.len(); i++) {
config.witnessSetBuilder.add_plutus_datum(plutus_datums.get(i));
}
}
const txWitnessSet = config.witnessSetBuilder.build();
const signedTx = CML.Transaction.new(
config.txComplete.body(),
txWitnessSet,
true,
config.txComplete.auxiliary_data()
);
const wallet = yield* pipe8(
Effect16.fromNullable(config.wallet),
Effect16.orElseFail(() => signError(ERROR_MESSAGE.MISSING_WALLET))
);
return makeSubmit(wallet, signedTx);
}).pipe(Effect16.catchAllDefect((cause) => new RunTimeError({ cause })));
// src/tx-sign-builder/TxSignBuilder.ts
var makeTxSignBuilder = (wallet, tx) => {
const redeemers = tx.witness_set().redeemers();
const exUnits = { cpu: 0, mem: 0 };
if (redeemers) {
const arrLegacyRedeemer = redeemers?.as_arr_legacy_redeemer();
if (arrLegacyRedeemer) {
for (let i = 0; i < arrLegacyRedeemer.len(); i++) {
const redeemer = arrLegacyRedeemer.get(i);
exUnits.cpu += parseInt(redeemer.ex_units().steps().toString());
exUnits.mem += parseInt(redeemer.ex_units().mem().toString());
}
}
const mapRedeemerKeyToRedeemerVal = redeemers?.as_map_redeemer_key_to_redeemer_val();
if (mapRedeemerKeyToRedeemerVal) {
const keys = mapRedeemerKeyToRedeemerVal.keys();
for (let i = 0; i < (keys.len() || 0); i++) {
const key = keys.get(i);
const value = mapRedeemerKeyToRedeemerVal.get(key);
exUnits.cpu += parseInt(value.ex_units().steps().toString());
exUnits.mem += parseInt(value.ex_units().mem().toString());
}
}
}
const config = {
txComplete: tx,
witnessSetBuilder: CML.TransactionWitnessSetBuilder.new(),
programs: [],
wallet,
fee: parseInt(tx.body().fee().toString()),
exUnits
};
const txSignBuilder = {
sign: {
withWallet: () => {
const program = withWallet(config);
config.programs.push(program);
return txSignBuilder;
},
withPrivateKey: (privateKey) => {
const program = withPrivateKey(config, privateKey);
config.programs.push(program);
return txSignBuilder;
}
},
partialSign: {
withWallet: () => makeReturn(partialWithWallet(config)).unsafeRun(),
withWalletEffect: () => partialWithWallet(config),
withWalletSafe: () => makeReturn(partialWithWallet(config)).safeRun(),
withPrivateKey: (privateKey) => makeReturn(partialWithPrivateKey(config, privateKey)).unsafeRun(),
withPrivateKeyEffect: (privateKey) => partialWithPrivateKey(config, privateKey),
withPrivateKeySafe: (privateKey) => makeReturn(partialWithPrivateKey(config, privateKey)).safeRun()
},
assemble: (witnesses) => {
const program = assemble(config, witnesses);
config.programs.push(program);
return txSignBuilder;
},
toCBOR: (options = { canonical: false }) => options.canonical ? config.txComplete.to_canonical_cbor_hex() : config.txComplete.to_cbor_hex(),
toTransaction: () => config.txComplete,
toJSON: () => S3.decodeUnknownSync(S3.parseJson(S3.Object))(config.txComplete.to_json()),
toHash: () => CML.hash_transaction(config.txComplete.body()).to_hex(),
complete: () => makeReturn(completeTxSigner(config)).unsafeRun(),
completeProgram: () => completeTxSigner(config),
completeSafe: () => makeReturn(completeTxSigner(config)).safeRun()
};
return txSignBuilder;
};
// src/tx-builder/internal/CompleteTxBuilder.ts
import {
assetsToValue as assetsToValue2,
coreToTxOutput as coreToTxOutput2,
isEqualUTxO,
selectUTxOs,
sortUTxOs,
stringify,
utxoToCore as utxoToCore3,
utxoToTransactionInput,
utxoToTransactionOutput,
toCMLRedeemerTag
} from "@lucid-evolution/utils";
import { SLOT_CONFIG_NETWORK } from "@lucid-evolution/plutus";
import { isError } from "effect/Predicate";
var completeTxError = (cause) => new TxBuilderError({ cause: `{ Complete: ${cause} }` });
var complete = (options = {}) => Effect17.gen(function* () {
const { config } = yield* TxConfig;
const wallet = yield* pipe9(
Effect17.fromNullable(config.lucidConfig.wallet),
Effect17.orElseFail(() => completeTxError(ERROR_MESSAGE.MISSING_WALLET))
);
const walletAddress = yield* Effect17.promise(() => wallet.address());
const {
coinSelection = true,
changeAddress = walletAddress,
localUPLCEval = true,
setCollateral = 5000000n,
canonical = false,
includeLeftoverLovelaceAsFee = false,