1

I've got the following code which produces a signed continuation command. I've tried to add the pactCode key to the contCmd and use Pact.fetch.local but that does not work, I get error TypeError: pactCode must be a string: undefined.

What is the correct way to sign and send a prepared cont command to a local or send endpoint?

const Pact = require('pact-lang-api');
const NETWORK_ID = "mainnet01";
const CHAIN_ID = "8";
const API_HOST = `https://api.chainweb.com/chainweb/0.0/${NETWORK_ID}/chain/${CHAIN_ID}/pact`;

// Define the necessary transaction details
const keyPairs = {
    publicKey: '4aab9f08f1bd86c3ce007a9a87225ef061c09e7062efa622e2fd704c24514cfa',
    secretKey: 'secret-key'
}
const step = 1;
const rollback = false;
const envData = null;
const seller = "k:79464b986676c7b39f2202b09fcbbaf324c677c43122c62de76edaf9f0ca10bd";
const buyer = "k:4aab9f08f1bd86c3ce007a9a87225ef061c09e7062efa622e2fd704c24514cfa";
const amount = 1.0;
const price = 1000.0;
const pactId = "FdFn_GVF4f5IEOcsx8gvmWbQghMbY65rpwcfSdStgag";
const saleId = "n7Erm5Gcij3ITgOF3vXUww8j6MZgIGRSSeU0uCYcmKg";
const sender = "k:4aab9f08f1bd86c3ce007a9a87225ef061c09e7062efa622e2fd704c24514cfa";
const chainId = "8";
const gasPrice = 0.0000001;
const gasLimit = 10000;
const creationTime = Math.floor(new Date().getTime() / 1000);
const ttl = 28800; // Time to live in seconds
const meta = Pact.lang.mkMeta(sender, chainId, gasPrice, gasLimit, creationTime, ttl);


async function getProof() {
    const cmd1  =  {
        requestKey: "FdFn_GVF4f5IEOcsx8gvmWbQghMbY65rpwcfSdStgag",
        targetChainId: "8",
    };
    let proof = await Pact.fetch.spv(cmd1, API_HOST);
    return proof;
    // console.log(proof);
}
let result = "";
const proofPromise = getProof();
proofPromise.then(proofPromise => {
    result = proofPromise;
  });

  async function main() {
    let result = await getProof();
    // Prepare the continuation command
    const contCommand = Pact.api.prepareContCmd(
        {
            publicKey: keyPairs.publicKey,
            clist: [
                {
                    name: "marmalade.ledger.BUY",
                    args: [
                        "t:KNl_38B4fqeJd2ijPghc_ihD-5viRvqLcV10MZEIwsA",
                        buyer,
                        seller,
                        amount, // always 1.0 for NFTs
                        { int: 99999999 }, //timeout, which is set by the seller
                        saleId,
                    ],
                },
                {
                    name: "coin.TRANSFER",
                    args: [
                        buyer,
                        seller,
                        price,
                    ],
                },
                {
                    name: "coin.GAS",
                    args: []
                }
            ]
        }, new Date().toISOString(), null, pactId, rollback, step, envData, meta, NETWORK_ID);
        console.log(contCommand);
// console.log(contCommand);
        const signedCmd = Pact.crypto.sign(contCommand.cmd, keyPairs);
        contCommand.sigs = [
        {
            sig: signedCmd.sig,
        },
    ];
        Pact.fetch.local(contCommand, API_HOST)
            .then(response => {
                console.log("Transaction response:", response);
            })
            .catch(error => {
                console.error("Error sending transaction:", error);
            });
}
main();
Nexion21
  • 309
  • 2
  • 7

1 Answers1

2

First: you don't need pact code for calling continuation command, (remove that step).

Second: last parameter in marmalade.ledger.BUY is not pact-id it is actually sale-id, as per marmalade ledger smart contract (id:string seller:string amount:decimal timeout:integer sale-id:string)

Third: you have to add name: "coin.GAS", args: [] capability (otherwise you will get gas error).

Forth: sale-proof is optional (only needed for cross-chain/x-chain trx).