Anastasia-Labs / lucid-evolution

https://anastasia-labs.github.io/lucid-evolution/
40 stars 15 forks source link

Default min_ada issue. #57

Closed golddydev closed 4 months ago

golddydev commented 5 months ago

I have this code.

const assets = {}
lucid.newTx().pay.ToAddressWithData(
  self,
  {
    kind: "inline",
    value: Data.void(),
  },
  assets,
  validator
)

This throws an error. Because I didn't provide lovelace in assets. Should lovelace be set to min_ada by default?

SynthLuvr commented 5 months ago

Monkey patch:

import CML from "@dcspark/cardano-multiplatform-lib-nodejs";
import { Assets, Script } from "@lucid-evolution/core-types";
import { LucidEvolution, OutputDatum, TxBuilder } from "@lucid-evolution/lucid";
import { assetsToValue, toScriptRef } from "@lucid-evolution/utils";

const patch = (lucid: LucidEvolution) => {
  const newTx = lucid.newTx;

  lucid.newTx = () => {
    const builder = newTx();
    overrideToAddress(lucid, builder);
    overrideToAddressWithData(lucid, builder);
    overrideToContract(lucid, builder);
    return builder;
  };

  return lucid;
};

const overrideToAddress = (lucid: LucidEvolution, builder: TxBuilder) => {
  const ToAddress = builder.pay.ToAddress;

  builder.pay.ToAddress = function (
    this: TxBuilder,
    address: string,
    assets: Assets
  ) {
    return ToAddress(address, {
      ...assets,
      lovelace:
        assets["lovelace"] ?? calculateMinLovelace(lucid, address, assets),
    });
  };
};

const overrideToAddressWithData = (
  lucid: LucidEvolution,
  builder: TxBuilder
) => {
  const ToAddressWithData = builder.pay.ToAddressWithData;

  builder.pay.ToAddressWithData = function (
    this: TxBuilder,
    address: string,
    outputDatum: OutputDatum,
    assets: Assets,
    scriptRef?: Script | undefined
  ) {
    return ToAddressWithData(
      address,
      outputDatum,
      {
        ...assets,
        lovelace:
          assets["lovelace"] ??
          calculateMinLovelace(lucid, address, assets, outputDatum, scriptRef),
      },
      scriptRef
    );
  };
};

const overrideToContract = (lucid: LucidEvolution, builder: TxBuilder) => {
  const ToContract = builder.pay.ToContract;

  builder.pay.ToContract = function (
    this: TxBuilder,
    address: string,
    outputDatum: OutputDatum,
    assets: Assets,
    scriptRef?: Script | undefined
  ) {
    return ToContract(
      address,
      outputDatum,
      {
        ...assets,
        lovelace:
          assets["lovelace"] ??
          calculateMinLovelace(lucid, address, assets, outputDatum, scriptRef),
      },
      scriptRef
    );
  };
};

const calculateMinLovelace = (
  lucid: LucidEvolution,
  address: string,
  assets: Assets,
  outputDatum?: OutputDatum | undefined,
  scriptRef?: Script | undefined
): bigint => {
  const txAddress = CML.Address.from_bech32(address);
  const txAssets = assetsToValue({ ...assets, lovelace: 2000000n });
  const tx = (() => {
    if (!outputDatum) return CML.TransactionOutput.new(txAddress, txAssets);

    if (!scriptRef)
      return CML.TransactionOutput.new(
        txAddress,
        txAssets,
        toDatumOption(outputDatum)
      );

    return CML.TransactionOutput.new(
      txAddress,
      txAssets,
      toDatumOption(outputDatum),
      toScriptRef(scriptRef)
    );
  })();

  return CML.min_ada_required(
    tx,
    lucid.config().protocolParameters.coinsPerUtxoByte
  );
};

const toDatumOption = (outputDatum: OutputDatum): CML.DatumOption => {
  switch (outputDatum.kind) {
    case "hash":
      return CML.DatumOption.new_hash(
        CML.DatumHash.from_hex(outputDatum.value)
      );

    case "asHash": {
      const plutusData = CML.PlutusData.from_cbor_hex(outputDatum.value);
      return CML.DatumOption.new_hash(CML.hash_plutus_data(plutusData));
    }

    case "inline": {
      const plutusData = CML.PlutusData.from_cbor_hex(outputDatum.value);
      return CML.DatumOption.new_datum(plutusData);
    }
  }
};

export default patch;
solidsnakedev commented 5 months ago

fix, https://github.com/Anastasia-Labs/lucid-evolution/pull/110