UNPKG

@lucid-evolution/lucid

Version:

Next-generation transaction builder for highly scalable dApps on Cardano

1,285 lines (1,258 loc) 95.1 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { CML: () => CML, ERROR_MESSAGE: () => ERROR_MESSAGE, Lucid: () => Lucid, NullableError: () => NullableError, RunTimeError: () => RunTimeError, TxBuilderError: () => TxBuilderError, TxSignerError: () => TxSignerError, TxSubmitError: () => TxSubmitError, UnauthorizedNetwork: () => UnauthorizedNetwork, makeReturn: () => makeReturn, makeSubmit: () => makeSubmit, makeTxBuilder: () => makeTxBuilder, makeTxSignBuilder: () => makeTxSignBuilder }); module.exports = __toCommonJS(index_exports); // src/core.ts var import_effect = require("effect"); var CML = __toESM(require("@anastasia-labs/cardano-multiplatform-lib-nodejs"), 1); var makeReturn = (program) => { return { unsafeRun: () => import_effect.Effect.runPromise(program), safeRun: () => import_effect.Effect.runPromise(import_effect.Effect.either(program)), program: () => program }; }; // src/lucid-evolution/utils.ts var import_utils = require("@lucid-evolution/utils"); var import_plutus = require("@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 import_plutus.Data.from(utxo.datum, type); }; var metadataOf = async (provider, unit) => { const { policyId, name, label } = (0, import_utils.fromUnit)(unit); switch (label) { case 222: case 333: case 444: { const utxo = await provider.getUtxoByUnit((0, import_utils.toUnit)(policyId, name, 100)); const metadata = await datumOf(provider, utxo); return import_plutus.Data.toJson(metadata.fields[0]); } default: throw new Error("No variant matched."); } }; // src/lucid-evolution/LucidEvolution.ts var import_utils13 = require("@lucid-evolution/utils"); // src/tx-builder/internal/Collect.ts var import_effect5 = require("effect"); var import_plutus2 = require("@lucid-evolution/plutus"); var import_utils3 = require("@lucid-evolution/utils"); // src/Errors.ts var import_effect2 = require("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 import_effect2.Data.TaggedError("NullableError") { }; var UnauthorizedNetwork = class extends import_effect2.Data.TaggedError( "UnauthorizedNetwork" ) { }; var TxBuilderError = class extends import_effect2.Data.TaggedError("TxBuilderError") { get message() { return `${this.cause}`; } }; var TxSignerError = class extends import_effect2.Data.TaggedError("TxSignerError") { get message() { return `${this.cause}`; } }; var TxSubmitError = class extends import_effect2.Data.TaggedError("TxSubmitError") { get message() { return `${this.cause}`; } }; var RunTimeError = class extends import_effect2.Data.TaggedError("RunTimeError") { get message() { return `${this.cause}`; } }; // src/tx-builder/internal/Collect.ts var CML3 = __toESM(require("@anastasia-labs/cardano-multiplatform-lib-nodejs"), 1); // src/tx-builder/internal/TxUtils.ts var CML2 = __toESM(require("@anastasia-labs/cardano-multiplatform-lib-nodejs"), 1); var import_effect3 = require("effect"); var import_utils2 = require("@lucid-evolution/utils"); var txBuilderError = (cause) => new TxBuilderError({ cause: `{ TxBuilderError : ${cause} }` }); var toCMLAddress = (address, lucidConfig) => import_effect3.Effect.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) => import_effect3.Effect.gen(function* ($) { const addressDetails = yield* $( import_effect3.Effect.try({ try: () => (0, import_utils2.getAddressDetails)(address), catch: (cause) => new TxBuilderError({ cause }) }) ); const actualNetworkId = (0, import_utils2.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) => import_effect3.Effect.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* (0, import_effect3.pipe)( import_effect3.Effect.fromNullable(config.scripts.get(stakeCredential.hash)), import_effect3.Effect.orElseFail( () => txBuilderError(ERROR_MESSAGE.MISSING_SCRIPT(stakeCredential.hash)) ) ); const addPlutusCertificate = (scriptVersion) => { return import_effect3.Effect.gen(function* () { const red = yield* (0, import_effect3.pipe)( import_effect3.Effect.fromNullable(redeemer), import_effect3.Effect.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) => import_effect3.Effect.gen(function* () { const addressDetails = yield* (0, import_effect3.pipe)( validateAddressDetails(rewardAddress, config.lucidConfig), import_effect3.Effect.andThen( (address) => address.type !== "Reward" ? txBuilderError(ERROR_MESSAGE.MISSING_REWARD_TYPE) : import_effect3.Effect.succeed(address) ) ); const stakeCredential = yield* (0, import_effect3.pipe)( import_effect3.Effect.fromNullable(addressDetails.stakeCredential), import_effect3.Effect.orElseFail( () => txBuilderError(ERROR_MESSAGE.MISSING_STAKE_CREDENTIAL) ) ); return stakeCredential; }); var resolveDatum = (datumHash, datum, provider) => import_effect3.Effect.gen(function* () { if (!datumHash || datum) return datum; return yield* import_effect3.Effect.tryPromise({ try: () => provider.getDatum(datumHash), catch: txBuilderError }); }); // src/tx-builder/internal/Collect.ts var import_utils4 = require("@lucid-evolution/utils"); // src/tx-builder/internal/Service.ts var import_effect4 = require("effect"); var TxConfig = class extends import_effect4.Context.Tag("TxConfig")() { }; // src/tx-builder/internal/Collect.ts var collectError = (cause) => new TxBuilderError({ cause: `{ Collect: ${cause} }` }); var collectFromUTxO = (utxos, collectInputs = true) => (redeemer) => import_effect5.Effect.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( (0, import_utils3.utxoToCore)({ ...utxo, datum: resolvedDatum }) ); const credential = (0, import_utils4.paymentCredentialOf)(utxo.address); if (credential.type == "Script") { const script = yield* (0, import_effect5.pipe)( import_effect5.Effect.fromNullable(config.scripts.get(credential.hash)), import_effect5.Effect.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* (0, import_effect5.pipe)( import_effect5.Effect.fromNullable(redeemer), import_effect5.Effect.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* (0, import_effect5.pipe)( import_effect5.Effect.fromNullable(redeemer), import_effect5.Effect.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* (0, import_effect5.pipe)( import_effect5.Effect.fromNullable(redeemer), import_effect5.Effect.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) => import_effect5.Effect.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* import_effect5.Effect.tryPromise({ try: () => datumOf(config.lucidConfig.provider, utxo), catch: (cause) => collectError({ cause }) }); utxo.datum = import_plutus2.Data.to(data); } config.collectedInputs.push(utxo); } const partialProgram = collectFromUTxO(utxos, false); config.partialPrograms.set(redeemerBuilder, partialProgram); }); // src/tx-builder/internal/Read.ts var import_effect6 = require("effect"); var import_utils6 = require("@lucid-evolution/utils"); var readError = (cause) => new TxBuilderError({ cause: `{ Read : ${cause} }` }); var readFrom = (utxos) => import_effect6.Effect.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 = (0, import_utils6.utxoToCore)({ ...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 var import_utils7 = require("@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((0, import_utils7.applyDoubleCborEncoding)(script)).hash().to_hex(), value: { type, script: (0, import_utils7.applyDoubleCborEncoding)(script) } }; case "PlutusV2": return { key: CML.PlutusV2Script.from_cbor_hex((0, import_utils7.applyDoubleCborEncoding)(script)).hash().to_hex(), value: { type, script: (0, import_utils7.applyDoubleCborEncoding)(script) } }; case "PlutusV3": return { key: CML.PlutusV3Script.from_cbor_hex((0, import_utils7.applyDoubleCborEncoding)(script)).hash().to_hex(), value: { type, script: (0, import_utils7.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 var import_effect7 = require("effect"); var import_utils8 = require("@lucid-evolution/utils"); var payError = (cause) => new TxBuilderError({ cause: `{ Pay: ${cause} }` }); var payToAddress = (address, assets) => import_effect7.Effect.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 = (0, import_utils8.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 = (0, import_utils8.addAssets)( config.totalOutputAssets, (0, import_utils8.valueToAssets)(outputResult.output().amount()) ); config.payToOutputs = [ ...config.payToOutputs, (0, import_utils8.coreToTxOutput)(outputResult.output()) ]; config.txBuilder.add_output(outputResult); }); var ToAddressWithData = (address, outputDatum, assets, scriptRef) => import_effect7.Effect.gen(function* () { const { config } = yield* TxConfig; const outputBuilder = buildBaseOutput(address, outputDatum, scriptRef); assets ??= {}; const value = (0, import_utils8.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 = (0, import_utils8.addAssets)( config.totalOutputAssets, (0, import_utils8.valueToAssets)(outputResult.output().amount()) ); config.payToOutputs = [ ...config.payToOutputs, (0, import_utils8.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((0, import_utils8.toScriptRef)(scriptRef)).next() : baseBuilder.next(); }; // src/tx-builder/internal/Mint.ts var import_effect8 = require("effect"); var CML4 = __toESM(require("@anastasia-labs/cardano-multiplatform-lib-nodejs"), 1); var mintError = (cause) => new TxBuilderError({ cause: `{ Mint: ${cause} }` }); var mintAssets = (assets) => (redeemer) => import_effect8.Effect.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* (0, import_effect8.pipe)( import_effect8.Effect.fromNullable(config.scripts.get(policyId)), import_effect8.Effect.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* (0, import_effect8.pipe)( import_effect8.Effect.fromNullable(redeemer), import_effect8.Effect.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* (0, import_effect8.pipe)( import_effect8.Effect.fromNullable(redeemer), import_effect8.Effect.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* (0, import_effect8.pipe)( import_effect8.Effect.fromNullable(redeemer), import_effect8.Effect.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 var import_effect9 = require("effect"); var import_utils9 = require("@lucid-evolution/utils"); var validFrom = (unixTime) => import_effect9.Effect.gen(function* () { const { config } = yield* TxConfig; const slot = (0, import_utils9.unixTimeToSlot)(config.lucidConfig.network, unixTime); config.txBuilder.set_validity_start_interval(BigInt(slot)); }); var validTo = (unixTime) => import_effect9.Effect.gen(function* () { const { config } = yield* TxConfig; const slot = (0, import_utils9.unixTimeToSlot)(config.lucidConfig.network, unixTime); config.txBuilder.set_ttl(BigInt(slot)); }); // src/tx-builder/internal/Signer.ts var import_effect10 = require("effect"); var CML5 = __toESM(require("@anastasia-labs/cardano-multiplatform-lib-nodejs"), 1); var addSignerError = (cause) => new TxBuilderError({ cause: `{ Signer: ${cause} }` }); var addSigner = (address) => import_effect10.Effect.gen(function* () { const { config } = yield* TxConfig; const addressDetails = yield* validateAddressDetails( address, config.lucidConfig ); const credential = addressDetails.type === "Reward" ? yield* (0, import_effect10.pipe)( import_effect10.Effect.fromNullable(addressDetails.stakeCredential), import_effect10.Effect.orElseFail( () => addSignerError(ERROR_MESSAGE.MISSING_STAKE_CREDENTIAL) ) ) : yield* (0, import_effect10.pipe)( import_effect10.Effect.fromNullable(addressDetails.paymentCredential), import_effect10.Effect.orElseFail( () => addSignerError(ERROR_MESSAGE.MISSING_PAYMENT_CREDENTIAL) ) ); if (credential.type === "Script") yield* addSignerError(ERROR_MESSAGE.SCRIPT_CREDENTIAL_NOT_ALLOWED); return credential.hash; }).pipe(import_effect10.Effect.flatMap((keyHash) => addSignerKey(keyHash))); var addSignerKey = (keyHash) => import_effect10.Effect.gen(function* () { const { config } = yield* TxConfig; config.txBuilder.add_required_signer(CML5.Ed25519KeyHash.from_hex(keyHash)); }); // src/tx-builder/internal/Stake.ts var import_effect11 = require("effect"); var CML6 = __toESM(require("@anastasia-labs/cardano-multiplatform-lib-nodejs"), 1); var stakeError = (cause) => new TxBuilderError({ cause: `{ Stake: ${cause} }` }); var registerStake = (rewardAddress) => import_effect11.Effect.gen(function* () { const { config } = yield* TxConfig; const addressDetails = yield* (0, import_effect11.pipe)( validateAddressDetails(rewardAddress, config.lucidConfig), import_effect11.Effect.andThen( (address) => address.type !== "Reward" ? stakeError(ERROR_MESSAGE.MISSING_REWARD_TYPE) : import_effect11.Effect.succeed(address) ) ); const stakeCredential = yield* (0, import_effect11.pipe)( import_effect11.Effect.fromNullable(addressDetails.stakeCredential), import_effect11.Effect.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) => import_effect11.Effect.gen(function* () { const { config } = yield* TxConfig; const addressDetails = yield* (0, import_effect11.pipe)( validateAddressDetails(rewardAddress, config.lucidConfig), import_effect11.Effect.andThen( (address) => address.type !== "Reward" ? stakeError(ERROR_MESSAGE.MISSING_REWARD_TYPE) : import_effect11.Effect.succeed(address) ) ); const stakeCredential = yield* (0, import_effect11.pipe)( import_effect11.Effect.fromNullable(addressDetails.stakeCredential), import_effect11.Effect.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* (0, import_effect11.pipe)( import_effect11.Effect.fromNullable(config.scripts.get(stakeCredential.hash)), import_effect11.Effect.orElseFail( () => stakeError(ERROR_MESSAGE.MISSING_SCRIPT(stakeCredential.hash)) ) ); const handleRedeemer = () => (0, import_effect11.pipe)( import_effect11.Effect.fromNullable(redeemer), import_effect11.Effect.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) => import_effect11.Effect.gen(function* () { const { config } = yield* TxConfig; const addressDetails = yield* (0, import_effect11.pipe)( validateAddressDetails(rewardAddress, config.lucidConfig), import_effect11.Effect.andThen( (address) => address.type !== "Reward" ? stakeError(ERROR_MESSAGE.MISSING_REWARD_TYPE) : import_effect11.Effect.succeed(address) ) ); const withdrawBuilder = yield* (0, import_effect11.pipe)( import_effect11.Effect.fromNullable( CML6.RewardAddress.from_address( CML6.Address.from_bech32(rewardAddress) ) ), import_effect11.Effect.orElseFail( () => stakeError(ERROR_MESSAGE.MISSING_STAKE_CREDENTIAL) ), import_effect11.Effect.andThen( (address) => CML6.SingleWithdrawalBuilder.new(address, amount) ) ); const stakeCredential = yield* (0, import_effect11.pipe)( import_effect11.Effect.fromNullable(addressDetails.stakeCredential), import_effect11.Effect.orElseFail( () => stakeError(ERROR_MESSAGE.MISSING_STAKE_CREDENTIAL) ) ); const handleRedeemer = () => (0, import_effect11.pipe)( import_effect11.Effect.fromNullable(redeemer), import_effect11.Effect.orElseFail(() => stakeError(ERROR_MESSAGE.MISSING_REDEEMER)) ); switch (stakeCredential.type) { case "Key": { config.txBuilder.add_withdrawal(withdrawBuilder.payment_key()); break; } case "Script": { const script = yield* (0, import_effect11.pipe)( import_effect11.Effect.fromNullable(config.scripts.get(stakeCredential.hash)), import_effect11.Effect.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 var import_effect12 = require("effect"); var CML7 = __toESM(require("@anastasia-labs/cardano-multiplatform-lib-nodejs"), 1); var import_core_utils = require("@lucid-evolution/core-utils"); var poolError = (cause) => new TxBuilderError({ cause: `{ Pool : ${cause} }` }); var delegateTo = (rewardAddress, poolId, redeemer) => import_effect12.Effect.gen(function* () { const { config } = yield* TxConfig; const addressDetails = yield* (0, import_effect12.pipe)( validateAddressDetails(rewardAddress, config.lucidConfig), import_effect12.Effect.andThen( (address) => address.type !== "Reward" ? poolError(ERROR_MESSAGE.MISSING_REWARD_TYPE) : import_effect12.Effect.succeed(address) ) ); const stakeCredential = yield* (0, import_effect12.pipe)( import_effect12.Effect.fromNullable(addressDetails.stakeCredential), import_effect12.Effect.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* (0, import_effect12.pipe)( import_effect12.Effect.fromNullable(config.scripts.get(stakeCredential.hash)), import_effect12.Effect.orElseFail( () => poolError(ERROR_MESSAGE.MISSING_SCRIPT(stakeCredential.hash)) ) ); const handleRedeemer = () => (0, import_effect12.pipe)( import_effect12.Effect.fromNullable(redeemer), import_effect12.Effect.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 var CML8 = __toESM(require("@anastasia-labs/cardano-multiplatform-lib-nodejs"), 1); var import_effect13 = require("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) => import_effect13.Effect.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) => import_effect13.Effect.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) => import_effect13.Effect.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) => import_effect13.Effect.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) => import_effect13.Effect.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) => import_effect13.Effect.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) => import_effect13.Effect.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) => import_effect13.Effect.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) => import_effect13.Effect.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) => import_effect13.Effect.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 var import_effect14 = require("effect"); var S = __toESM(require("@effect/schema/Schema"), 1); var import_core_utils2 = require("@lucid-evolution/core-utils"); var attachMetadata = (config, label, metadata) => import_effect14.Effect.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: (0, import_core_utils2.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 var import_effect18 = require("effect"); var UPLC = __toESM(require("@lucid-evolution/uplc"), 1); // src/tx-sign-builder/TxSignBuilder.ts var S3 = __toESM(require("@effect/schema/Schema"), 1); // src/tx-sign-builder/internal/CompleteTxSigner.ts var import_effect17 = require("effect"); // src/tx-submit/TxSubmit.ts var import_effect15 = require("effect"); var S2 = __toESM(require("@effect/schema/Schema"), 1); var makeSubmit = (wallet, txSigned) => { const submit = (options) => import_effect15.Effect.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 var import_effect16 = require("effect"); var signError = (cause) => new TxSignerError({ cause }); var mkWitnessFromWallet = (wallet, txComplete) => (0, import_effect16.pipe)( import_effect16.Effect.fromNullable(wallet), import_effect16.Effect.catchAll(() => signError(ERROR_MESSAGE.MISSING_WALLET)), import_effect16.Effect.tryMapPromise({ try: (wallet2) => wallet2.signTx(txComplete), catch: (cause) => signError(cause) }) ); var withWallet = (config) => (0, import_effect16.pipe)( mkWitnessFromWallet(config.wallet, config.txComplete), import_effect16.Effect.map((witness) => config.witnessSetBuilder.add_existing(witness)) ); var partialWithWallet = (config) => (0, import_effect16.pipe)( mkWitnessFromWallet(config.wallet, config.txComplete), import_effect16.Effect.map((witness) => witness.to_cbor_hex()) ); var mkWitnessFromPrivateKey = (privateKey, txComplete) => (0, import_effect16.pipe)( import_effect16.Effect.try({ try: () => CML.PrivateKey.from_bech32(privateKey), catch: signError }), import_effect16.Effect.map( (privateKey2) => CML.make_vkey_witness( CML.hash_transaction(txComplete.body()), privateKey2 ) ) ); var withPrivateKey = (config, privateKey) => (0, import_effect16.pipe)( mkWitnessFromPrivateKey(privateKey, config.txComplete), import_effect16.Effect.map((witness) => config.witnessSetBuilder.add_vkey(witness)) ); var partialWithPrivateKey = (config, privateKey) => (0, import_effect16.pipe)( mkWitnessFromPrivateKey(privateKey, config.txComplete), import_effect16.Effect.map((witness) => { const witnessBuilder = CML.TransactionWitnessSetBuilder.new(); witnessBuilder.add_vkey(witness); return witnessBuilder.build().to_cbor_hex(); }) ); var assemble = (config, witnesses) => import_effect16.Effect.forEach( witnesses, (witness) => (0, import_effect16.pipe)( import_effect16.Effect.try({ try: () => CML.TransactionWitnessSet.from_cbor_hex(witness), catch: signError }), import_effect16.Effect.map((witness2) => config.witnessSetBuilder.add_existing(witness2)) ) ); // src/tx-sign-builder/internal/CompleteTxSigner.ts var completeTxSigner = (config) => import_effect17.Effect.gen(function* () { yield* impo