0

I've forked a dApp Connector I found on Github and I'm trying to add some transaction metadata to the ADA transaction it builds. This is what I currently have:

buildSendADATransaction = async () => {
    //metadata
    const messageData = {
      receiver_id: "SJKdj34k3jjKFDKfjFUDfdjkfd",
      sender_id: "jkfdsufjdk34h3Sdfjdhfduf873",
      comment: "happy birthday",
      tags: [0, 264, -1024, 32],
    };
    const generalMetadata = GeneralTransactionMetadata.new();
    console.log(Buffer.from(generalMetadata.to_bytes(), "hex").toString("hex"));

    generalMetadata.insert(
      BigNum.from_str("674"),
      encode_json_str_to_metadatum(JSON.stringify(messageData))
    );
    const _metadata = AuxiliaryData.new();
    _metadata.set_metadata(generalMetadata);

    console.log(`the metadata is ${_metadata.metadata()}`);

    // build tx
    const txBuilder = await this.initTransactionBuilder();

    const shelleyOutputAddress = Address.from_bech32(
      this.state.addressBech32SendADA
    );
    const shelleyChangeAddress = Address.from_bech32(this.state.changeAddress);

    txBuilder.add_output(
      TransactionOutput.new(
        shelleyOutputAddress,
        Value.new(BigNum.from_str(this.state.lovelaceToSend.toString()))
      )
    );

    // Find the available UTXOs in the wallet and
    // use them as Inputs
    const txUnspentOutputs = await this.getTxUnspentOutputs();
    txBuilder.add_inputs_from(txUnspentOutputs, 1);

    // calculate the min fee required and send any change to an address
    txBuilder.add_change_if_needed(shelleyChangeAddress);

    // once the transaction is ready, we build it to get the tx body without witnesses
    const txBody = txBuilder.build();
    txBody.set_auxiliary_data_hash(hash_auxiliary_data(_metadata));

    // Tx witness
    const transactionWitnessSet = TransactionWitnessSet.new();

    const tx = Transaction.new(
      txBody,
      TransactionWitnessSet.from_bytes(transactionWitnessSet.to_bytes()),
      _metadata
    );

    let txVkeyWitnesses = await this.API.signTx(
      Buffer.from(tx.to_bytes(), "utf8").toString("hex"),
      true
    );
    txVkeyWitnesses = TransactionWitnessSet.from_bytes(
      Buffer.from(txVkeyWitnesses, "hex")
    );

    transactionWitnessSet.set_vkeys(txVkeyWitnesses.vkeys());

    const txBodyFinal = tx.body();
    const signedTx = Transaction.new(
      txBodyFinal,
      transactionWitnessSet,
      _metadata
    );

    const submittedTxHash = await this.API.submitTx(
      Buffer.from(signedTx.to_bytes(), "utf8").toString("hex")
    );
    console.log(submittedTxHash);
    this.setState({ submittedTxHash });
  };

It constructs the transaction just fine with a wallet like Nami, but there's no metadata attached to that transaction. Any thoughts?

1
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.
    – Community Bot
    Mar 15, 2022 at 3:15

2 Answers 2

0

If you are open to integrating with wallets other than Nami Wallet,

Typhon Wallet DApp connector has simple, ready-to-call methods to build a transaction with metadata and/or tokens.

Below is transaction method that adds metadata to a transaction.

const auxiliaryDataCbor = typhonjs.utils
  .createAuxiliaryDataCbor({
    metadata: [
      {
        label: 674,
        data: {
          msg: ["This is a comment for the transaction xyz, thank you very much!"],
        },
      },
    ],
  })
  .toString("hex");

const paymentTransactionResponse = await typhon.paymentTransaction({
  auxiliaryDataCbor: auxiliaryDataCbor,
  outputs: [
    {
      address:
        "addr_test1qz7jw975stagnvs00wsjny6y6gpazn86yvwcm2vy02j3up7mt68vuzvz4nzgs00x0shrgywvy674v6r2zcs8fxvvq27qfjq8np",
      amount: "6000000",
    },
  ],
});

Example at https://docs.typhonwallet.io/examples/paymentTransaction.html#sending-metadata

https://typhonwallet.io

1
  • Yeah, I saw that -- but I'd prefer to stick with CSL, any thoughts? Mar 17, 2022 at 6:16
0

This answer is refferenced from https://cardanoupdates.com/commits/6af4284b32841a13ebe86fdcc6f10dd1d74ddfdc and I have used similar code in production. I haven't tested this function but you should get the idea.

buildSendADATransaction = async () => {
const messageData = {
    receiver_id: "SJKdj34k3jjKFDKfjFUDfdjkfd",
    sender_id: "jkfdsufjdk34h3Sdfjdhfduf873",
    comment: "happy birthday",
    tags: [0, 264, -1024, 32],
};

const txBuilder = await this.initTransactionBuilder();
const shelleyOutputAddress = Address.from_bech32(
    this.state.addressBech32SendADA
);
const shelleyChangeAddress = Address.from_bech32(this.state.changeAddress);

txBuilder.add_output(
    TransactionOutput.new(
        shelleyOutputAddress,
        Value.new(BigNum.from_str(this.state.lovelaceToSend.toString()))
    )
);

/////////////////////////////////
// Add metadata here

txBuilder.add_json_metadatum(
    BigNum.from_str("674"),
    JSON.stringify(messageData)
);
/////////////////////////////////


const txUnspentOutputs = await this.getTxUnspentOutputs();
txBuilder.add_inputs_from(txUnspentOutputs, 1);
txBuilder.add_change_if_needed(shelleyChangeAddress);
const txBody = txBuilder.build();

////////////////////////////
// Create unsigned tx with metadata included

const unsignedTransaction = txBuilder.build_tx();
/////////////////////////////

const transactionWitnessSet = TransactionWitnessSet.new();
const tx = Transaction.new(
    txBody,
    TransactionWitnessSet.from_bytes(transactionWitnessSet.to_bytes()),
    ///
    unsignedTransaction.auxiliary_data() // Include metadata

);
let txVkeyWitnesses = await this.API.signTx(
    Buffer.from(tx.to_bytes(), "utf8").toString("hex"),
    true
);
txVkeyWitnesses = TransactionWitnessSet.from_bytes(
    Buffer.from(txVkeyWitnesses, "hex")
);
transactionWitnessSet.set_vkeys(txVkeyWitnesses.vkeys());

const txBodyFinal = tx.body();
const signedTx = Transaction.new(
    txBodyFinal, 
    transactionWitnessSet,
    ///
    unsignedTransaction.auxiliary_data() // Include metadata

);

const submittedTxHash = await this.API.submitTx(
    Buffer.from(signedTx.to_bytes(), "utf8").toString("hex")
);
console.log(submittedTxHash);
this.setState({ submittedTxHash });};

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.