trufflesuite/truffle

View on GitHub
packages/encoder/lib/utils.ts

Summary

Maintainability
A
1 hr
Test Coverage
import BigNumber from "bignumber.js";
import { BigNumber as EthersBigNumber } from "@ethersproject/bignumber";
import escapeRegExp from "lodash/escapeRegExp";

// Unfortunately, both BigNumber and EthersBigNumber's isBigNumber methods
// **both return false positives on the other BigNumber class**.
// (This is because they both just check for the _isBigNumber flag.)
// As such, we've made our own method to recognize these, by
// A. using the appropriate method, but then also
// B. checking for the presence of a method that one class has but the other
// doesn't.

export function isBigNumber(input: any): input is BigNumber {
  return BigNumber.isBigNumber(input) && Boolean(input.toFixed);
}

export function isEthersBigNumber(input: any): input is EthersBigNumber {
  return EthersBigNumber.isBigNumber(input) && Boolean(input.toHexString);
}

interface Links {
  [libraryName: string]: string;
}

//warning: copied (OK, adapted) from Truffle Contract!
export function link(bytecode: string, links: Links): string {
  if (!bytecode) {
    return bytecode;
  }
  const names = Object.keys(links).sort((a, b) => b.length - a.length); //sort from longest to shortest
  //(this allows overlong names to be handled properly)
  for (const name of names) {
    const address = links[name];
    bytecode = bytecode.replace(
      //we have to escape as names may include '$'
      new RegExp(`__${escapeRegExp(name)}_*`, "g"),
      //note: we don't have to worry about link references running into
      //one another, because each one is always preceded by a PUSH20 (0x73)
      address.slice(2) //cut off initial 0x
    );
  }
  return bytecode;
}