CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-web3-eth-contract

Web3 module to interact with Ethereum smart contracts with TypeScript type safety

Pending
Overview
Eval results
Files

encoding-utilities.mddocs/

Encoding and Utilities

Low-level encoding, decoding, and utility functions for contract interaction, address generation, and transaction parameter management.

Capabilities

Method Encoding/Decoding

Functions for encoding method calls and decoding return values.

/**
 * Encode method ABI with parameters for contract calls
 * @param abi - The function or constructor fragment from contract ABI
 * @param args - Arguments to encode
 * @param deployData - Optional deployment bytecode for constructor calls
 * @returns Encoded method call data as hex string
 */
function encodeMethodABI(
  abi: AbiFunctionFragment | AbiConstructorFragment,
  args: unknown[],
  deployData?: HexString
): string;

/**
 * Decode method parameters from transaction input data
 * Alias for decodeFunctionCall from web3-eth-abi
 * @param abi - The function fragment from contract ABI
 * @param data - Encoded transaction input data
 * @returns Decoded parameters object
 */
function decodeMethodParams(
  abi: AbiFunctionFragment,
  data: HexString
): DecodedParams & { __method__: string; __length__: number };

/**
 * Decode method return values from transaction result
 * Alias for decodeFunctionReturn from web3-eth-abi
 * @param abi - The function fragment from contract ABI  
 * @param returnValues - Encoded return data
 * @returns Decoded return values
 */
function decodeMethodReturn(
  abi: AbiFunctionFragment,
  returnValues: HexString
): unknown;

Event Encoding/Decoding

Functions for encoding event filters and decoding event logs.

/**
 * Encode event ABI for log filtering
 * @param abi - The event fragment from contract ABI
 * @param options - Event filtering options
 * @returns Encoded filter with topics and block range
 */
function encodeEventABI(
  abi: AbiEventFragment,
  options?: ContractEventOptions
): {
  topics: Topic[];
  fromBlock?: BlockNumberOrTag;
};

/**
 * Decode event from log data (re-exported from web3-eth)
 * @param abi - The event fragment or full ABI
 * @param data - Log data to decode
 * @param topics - Log topics array
 * @param nonIndexedData - Non-indexed event data
 * @returns Decoded event data
 */
function decodeEventABI(
  abi: AbiEventFragment | ContractAbi,
  data: LogsInput,
  topics: string[],
  nonIndexedData?: string
): EventLog;

Address Generation

Utilities for generating contract addresses for deployment.

/**
 * Generate contract address using CREATE opcode (deterministic from deployer and nonce)
 * @param from - Deployer address
 * @param nonce - Transaction nonce
 * @returns Computed contract address
 */
function createContractAddress(from: Address, nonce: Numbers): Address;

/**
 * Generate contract address using CREATE2 opcode (deterministic from salt and init code)
 * @param from - Deployer address  
 * @param salt - Salt value for CREATE2
 * @param initCode - Contract initialization code
 * @returns Computed CREATE2 contract address
 */
function create2ContractAddress(
  from: Address,
  salt: Bytes,
  initCode: Bytes  
): Address;

Transaction Parameter Utilities

Internal utilities for preparing transaction parameters (exported for advanced usage).

/**
 * Get parameters for sending transactions
 * @param options - Contract transaction options
 * @param contractOptions - Contract default options
 * @returns Formatted transaction parameters
 */
function getSendTxParams(options: {
  options?: PayableCallOptions | NonPayableCallOptions;
  contractOptions?: ContractOptions;
}): TransactionCall;

/**
 * Get parameters for eth_call operations
 * @param options - Contract call options
 * @param contractOptions - Contract default options  
 * @returns Formatted call parameters
 */
function getEthTxCallParams(options: {
  options?: PayableCallOptions | NonPayableCallOptions;
  contractOptions?: ContractOptions;
}): TransactionCall;

/**
 * Get parameters for gas estimation
 * @param options - Contract gas estimation options
 * @param contractOptions - Contract default options
 * @returns Formatted gas estimation parameters
 */
function getEstimateGasParams(options: {
  options?: PayableCallOptions | NonPayableCallOptions;
  contractOptions?: ContractOptions;
}): TransactionCall;

/**
 * Get parameters for access list creation
 * @param options - Contract access list options
 * @param contractOptions - Contract default options
 * @returns Formatted access list parameters
 */
function getCreateAccessListParams(options: {
  options?: PayableCallOptions | NonPayableCallOptions;
  contractOptions?: ContractOptions;
}): TransactionForAccessList;

Context Validation

Utility for validating Web3 contract context objects.

/**
 * Type guard to check if an object is a Web3ContractContext
 * @param options - Object to check
 * @returns True if object is Web3ContractContext
 */
function isWeb3ContractContext(options: unknown): options is Web3ContractContext;

Usage Examples

Method Encoding

import { encodeMethodABI, decodeMethodParams, decodeMethodReturn } from "web3-eth-contract";

// Encode method call
const abi = {
  inputs: [
    { name: "to", type: "address" },
    { name: "amount", type: "uint256" }
  ],
  name: "transfer",
  outputs: [{ name: "", type: "bool" }],
  stateMutability: "nonpayable",
  type: "function"
} as const;

const encodedData = encodeMethodABI(
  abi,
  ["0x1234567890123456789012345678901234567890", "1000000000000000000"]
);
console.log("Encoded method call:", encodedData);
// Output: 0xa9059cbb000000000000000000000000123456789012345678901234567890123456789000000000000000000000000000000000000000000000000000de0b6b3a7640000

// Decode method parameters from transaction input
const decodedParams = decodeMethodParams(abi, encodedData);
console.log("Decoded parameters:", {
  to: decodedParams.to,
  amount: decodedParams.amount,
  method: decodedParams.__method__, // "transfer(address,uint256)"
  length: decodedParams.__length__ // 2
});

// Decode method return values
const returnData = "0x0000000000000000000000000000000000000000000000000000000000000001";
const decodedReturn = decodeMethodReturn(abi, returnData);
console.log("Method returned:", decodedReturn); // true

Event Encoding

import { encodeEventABI, decodeEventABI } from "web3-eth-contract";

// Encode event filter
const eventAbi = {
  anonymous: false,
  inputs: [
    { indexed: true, name: "from", type: "address" },
    { indexed: true, name: "to", type: "address" },
    { indexed: false, name: "value", type: "uint256" }
  ],
  name: "Transfer",
  type: "event"
} as const;

const encodedFilter = encodeEventABI(eventAbi, {
  filter: {
    from: "0x1234567890123456789012345678901234567890",
    to: ["0xabcd...", "0xefgh..."] // Multiple values
  },
  fromBlock: 1000000
});

console.log("Encoded filter:", {
  topics: encodedFilter.topics,
  fromBlock: encodedFilter.fromBlock
});

// Decode event from logs
const logData = {
  address: "0x...",
  topics: [
    "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", // Transfer signature
    "0x000000000000000000000000abcdefabcdefabcdefabcdefabcdefabcdefabcdef", // from
    "0x000000000000000000000000123456789012345678901234567890123456789" // to
  ],
  data: "0x00000000000000000000000000000000000000000000000000de0b6b3a7640000", // value
  blockNumber: 1000001
};

const decodedEvent = decodeEventABI(eventAbi, logData, logData.topics);
console.log("Decoded event:", {
  event: decodedEvent.event, // "Transfer"
  from: decodedEvent.returnValues.from,
  to: decodedEvent.returnValues.to,
  value: decodedEvent.returnValues.value
});

Contract Address Generation

import { createContractAddress, create2ContractAddress } from "web3-eth-contract";

// Generate address for CREATE deployment
const deployerAddress = "0x1234567890123456789012345678901234567890";
const nonce = 42;

const contractAddress = createContractAddress(deployerAddress, nonce);
console.log("CREATE contract address:", contractAddress);

// Generate address for CREATE2 deployment
const salt = "0x0000000000000000000000000000000000000000000000000000000000000001";
const initCode = "0x608060405234801561001057600080fd5b50..."; // Contract bytecode + constructor args

const create2Address = create2ContractAddress(deployerAddress, salt, initCode);
console.log("CREATE2 contract address:", create2Address);

// Pre-compute address before deployment
console.log("Contract will be deployed at:", create2Address);
// Deploy and verify
const deployedContract = await contract.deploy({
  data: initCode
}).send({ from: deployerAddress });
console.log("Actual deployed address:", deployedContract.options.address);
// Should match create2Address

Advanced Transaction Parameter Handling

import { 
  getSendTxParams, 
  getEstimateGasParams,
  getCreateAccessListParams 
} from "web3-eth-contract";

const contractOptions = {
  from: "0x1234567890123456789012345678901234567890",
  gas: 100000,
  gasPrice: "20000000000"
};

const callOptions = {
  from: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef",
  gas: 150000,
  value: "1000000000000000000" // 1 ETH
};

// Get parameters for sending transaction
const sendParams = getSendTxParams({
  options: callOptions,
  contractOptions
});
console.log("Send transaction params:", sendParams);
// Merged options with callOptions taking precedence

// Get parameters for gas estimation
const gasParams = getEstimateGasParams({
  options: callOptions,
  contractOptions
});
console.log("Gas estimation params:", gasParams);

// Get parameters for access list creation
const accessListParams = getCreateAccessListParams({
  options: callOptions,
  contractOptions
});
console.log("Access list params:", accessListParams);

Context Validation

import { isWeb3ContractContext } from "web3-eth-contract";

function handleContractInput(input: unknown) {
  if (isWeb3ContractContext(input)) {
    // TypeScript now knows input is Web3ContractContext
    console.log("Provider:", input.provider);
    console.log("Request manager:", input.requestManager);
    console.log("Config:", input.config);
  } else {
    console.log("Not a valid Web3ContractContext");
  }
}

// Test with various inputs
handleContractInput({
  provider: web3Provider,
  config: web3Config
}); // Valid context

handleContractInput({
  from: "0x123...",
  gas: 100000
}); // Not a context

Low-Level Contract Interaction

import { 
  encodeMethodABI, 
  createContractAddress,
  getSendTxParams 
} from "web3-eth-contract";
import { sendTransaction } from "web3-eth";

// Manual contract interaction without Contract class
async function manualContractCall() {
  const methodAbi = {
    inputs: [{ name: "value", type: "uint256" }],
    name: "setValue",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function"
  } as const;

  // Encode method call
  const encodedData = encodeMethodABI(methodAbi, [42]);
  
  // Prepare transaction parameters
  const txParams = getSendTxParams({
    options: {
      from: "0x1234567890123456789012345678901234567890",
      to: "0xcontractaddress...",
      data: encodedData,
      gas: 100000
    },
    contractOptions: {}
  });

  // Send transaction using web3-eth directly
  const receipt = await sendTransaction(web3, txParams);
  console.log("Transaction sent:", receipt.transactionHash);
}

Deployment Address Prediction

import { createContractAddress, create2ContractAddress } from "web3-eth-contract";

class DeploymentPlanner {
  private deployerAddress: string;
  private currentNonce: number;

  constructor(deployerAddress: string, currentNonce: number) {
    this.deployerAddress = deployerAddress;
    this.currentNonce = currentNonce;
  }

  predictNextContractAddress(): string {
    return createContractAddress(this.deployerAddress, this.currentNonce);
  }

  predictContractAddressAtNonce(nonce: number): string {
    return createContractAddress(this.deployerAddress, nonce);
  }

  predictCreate2Address(salt: string, initCode: string): string {
    return create2ContractAddress(this.deployerAddress, salt, initCode);
  }

  planDeployments(contracts: Array<{ name: string; bytecode: string; salt?: string }>) {
    const plan = contracts.map((contract, index) => {
      const address = contract.salt
        ? this.predictCreate2Address(contract.salt, contract.bytecode)
        : this.predictContractAddressAtNonce(this.currentNonce + index);
      
      return {
        name: contract.name,
        predictedAddress: address,
        deploymentMethod: contract.salt ? 'CREATE2' : 'CREATE'
      };
    });

    console.log("Deployment plan:", plan);
    return plan;
  }
}

// Usage
const planner = new DeploymentPlanner(
  "0x1234567890123456789012345678901234567890",
  await web3.eth.getTransactionCount("0x1234567890123456789012345678901234567890")
);

const deploymentPlan = planner.planDeployments([
  { name: "Token", bytecode: tokenBytecode },
  { name: "Exchange", bytecode: exchangeBytecode, salt: "0x01" }
]);

Install with Tessl CLI

npx tessl i tessl/npm-web3-eth-contract

docs

contract-deployment.md

contract-management.md

encoding-utilities.md

event-handling.md

index.md

method-execution.md

tile.json