Broadcast Transactions

Broadcast to the Network.

If you'd like your transactions to also be broadcast to the associated blockchain network for each ContractAction created, you can pass in the optional broadcast parameter as true to the start method.

await newCircuit.start({publicKey, ipfsCID, authSig, broadcast: true});

Please note that broadcast is only supported for ContractActions. If any of your transaction data is under funded or unapproved the broadcast will be unsuccessful and an error logged and thrown.

Make sure your PKP address or other wallets are correctly funded and approved on the network specified in each ContractAction.

For a more reliable and controlled experience it's suggested that you broadcast your transactions outside of the SDK, which is necessary anyway if you plan to broadcast any FetchAction or CustomAction signed data. Broadcasts are non blocking to each run of the circuit.

For a quick start to broadcasting your signed transactions, obtain the correct unsigned transaction data parameters returned in the SetActions object. You can also create this manually yourself by invoking generateUnsignedTransactionData .

// Generate or obtain the constructed unsigned transaction data.
const {unsignedTransactionDataObject, LitActionCode} = await newCircuit.setActions([contractAction]);

The unsignedTransactionDataObject is populated according to the number of ContractActions added in SetActions. Each field within this object is named in the following format: generatedUnsignedDataContract${priorityNumberOfTheAction}.

unsignedTransactionDataObject = {
      generatedUnsignedDataContract1: {
      "to": "0x123abc...",
      "nonce": 0,
      "chainId": 137,
      "gasLimit": { "_hex": "0x186a0", "_isBigNumber": true },
      "maxFeePerGas": { "_hex": "0x2dc6c0", "_isBigNumber": true },
      "maxPriorityFeePerGas": { "_hex": "0x16e360", "_isBigNumber": true },
      "from": "0xabc123...",
      "data": "0xa9059cbb0000000000000000000000005beeb...",
      "value": { "_hex": "0x0", "_isBigNumber": true },
      "type": 2
  },
      generatedUnsignedDataContract2: {
        "to": "0xdef456...",
        "nonce": 2,
        "chainId": 137,
        "gasLimit": { "_hex": "0x186a0", "_isBigNumber": true },
        "maxFeePerGas": { "_hex": "0x2dc6c0", "_isBigNumber": true },
        "maxPriorityFeePerGas": { "_hex": "0x16e360", "_isBigNumber": true },
        "from": "0x456def...",
        "data": "0xa9059cbb0000000000000000000000004abcf...",
        "value": { "_hex": "0x0", "_isBigNumber": true },
        "type": 2
  }
}

This transaction data can then be serialized alongside the returned s,r,recid values from the signed transaction response object in the LogCategory.RESPONSE field.

import { joinSignature } from "@ethersproject/bytes";

// The latestBroadcastLog will contain the broadcast information of the last signed transaction i.e. generatedUnsignedDataContract2. To access generatedUnsignedDataContract1 take newCircuit.getLogs(LogCategory.Broadcast)[1]. Assuming the circuit has done one execution run. 
const latestBroadcastLog = newCircuit.getLogs(LogCategory.Broadcast)[0];
const sig = JSON.parse(latestBroadcastLog.responseObject).signatures.contract1;

const encodedSignature = joinSignature({r: "0x" + sig.r, s: "0x" + sig.s, recoveryParam: sig.recid});

// Make sure your provider url and chainId matches the chain that was specified for the added contract action.
const provider = new ethers.providers.JsonRpcProvider("https://provider-url.com", 137);

// Serialize the correct tx data with the associated encoded signature.
const serialized = serialize(generatedUnsignedDataContract2,encodedSignature);

const transactionHash = await provider.sendTransaction(serialized);
await transactionHash.wait();

Last updated