@ethersproject/address#isAddress TypeScript Examples

The following examples show how to use @ethersproject/address#isAddress. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts    From ether-swr with MIT License 7 votes vote down vote up
call = (
  parameters: string[],
  provider: ethersProviders.Provider,
  ABIs
): Promise<any> => {
  const [address, method, ...otherParams] = parameters
  // it's a contract
  if (isAddress(address)) {
    if (!ABIs) throw new ABIError(`ABI repo not found`)
    if (!ABIs.get) throw new ABIError(`ABI repo isn't a Map`)
    const abi = ABIs.get(address)
    if (!abi) throw new ABINotFound(`ABI not found for ${address}`)
    const contract = new Contract(address, abi, provider)
    return contract[method](...otherParams)
  }
  const param2 = method
  const baseMethod = address // getBalance, getTransactionCount, etc
  return provider[baseMethod](param2, ...otherParams)
}
Example #2
Source File: utils.ts    From ether-swr with MIT License 7 votes vote down vote up
multiCall = (
  parameters: string | any[],
  provider: providers.MulticallProvider,
  ABIs
) => {
  const {
    params: [address, method, otherParams],
    extended
  } = parseParams(parameters)

  // it's a contract
  if (isAddress(address)) {
    if (!ABIs) throw new ABIError(`ABI repo not found`)
    if (!ABIs.get) throw new ABIError(`ABI repo isn't a Map`)
    const abi = ABIs.get(address)
    if (!abi) throw new ABINotFound(`ABI not found for ${address}`)
    const contract = new Contract(address, abi, provider)
    return contract[method](...otherParams, extended)
  }
  const param2 = method
  const baseMethod = address
  return provider[baseMethod](param2, ...otherParams, extended.blockTag)
}
Example #3
Source File: index.ts    From snapshot-plugins with MIT License 6 votes vote down vote up
validateTransaction(transaction: ModuleTransaction) {
    const addressEmptyOrValidate =
      transaction.to === '' || isAddress(transaction.to);
    return (
      isBigNumberish(transaction.value) &&
      addressEmptyOrValidate &&
      (!transaction.data || isHexString(transaction.data)) &&
      transaction.operation in ['0', '1'] &&
      isBigNumberish(transaction.nonce)
    );
  }
Example #4
Source File: NameTags.tsx    From useDApp with MIT License 5 votes vote down vote up
export function NameTags({ onNavigate }: Props) {
  const [nameTags, setNameTags] = useNameTags()
  const [address, setAddress] = useState('')
  const [name, setName] = useState('')
  const [error, setError] = useState('')

  function onSubmit(e: FormEvent) {
    e.preventDefault()

    if (!isAddress(address)) {
      setError('Invalid address')
      return
    } else if (!name) {
      setError('No name specified')
      return
    }

    setNameTags([...nameTags, { address, name }])
    setError('')
    setAddress('')
    setName('')
  }

  function onRemove(i: number) {
    setNameTags(nameTags.filter((x, index) => index !== i))
  }

  const displayed = useMemo(
    () =>
      nameTags
        .map((tag) => ({ ...tag, address: getAddress(tag.address) }))
        .map((tag, i, array) => ({
          ...tag,
          shadowed: array.some((x, j) => j > i && x.address.toLowerCase() === tag.address.toLowerCase()),
        })),
    [nameTags]
  )

  return (
    <Page name="nameTags" onNavigate={onNavigate}>
      <Wrapper>
        <Title>Name Tag Manager</Title>
        <Text>
          Name tags are used for identifying Ethereum addresses. Instead of remembering the hex values you can assign a
          human readable name to them. This names are used across this extension. Some addresses and names are added
          automatically (e.g. connected accounts or multicall contracts). Those can be changed at any point.
        </Text>
        <Form onSubmit={onSubmit}>
          <AddressInput value={address} onChange={(e) => setAddress(e.target.value)} placeholder="Address 0x1234..." />
          <Input value={name} onChange={(e) => setName(e.target.value)} placeholder="Name tag" />
          <SubmitButton type="submit" value="Add" />
        </Form>
        {error && <ErrorMessage>{error}</ErrorMessage>}
        <Table>
          <tbody>
            {displayed
              .map((tag, i) => (
                <Row key={i}>
                  <AddressCell className={tag.shadowed ? 'shadowed' : ''}>{tag.address}</AddressCell>
                  <NameCell className={tag.shadowed ? 'shadowed' : ''}>{tag.name}</NameCell>
                  <Cell>
                    <Remove onClick={() => onRemove(i)}>Remove</Remove>
                  </Cell>
                </Row>
              ))
              .reverse()}
          </tbody>
        </Table>
      </Wrapper>
    </Page>
  )
}
Example #5
Source File: useEtherSWR.ts    From ether-swr with MIT License 5 votes vote down vote up
buildContract = (target: string, config: EthSWRConfigInterface) => {
  if (!isAddress(target)) return undefined
  const abi = config.ABIs.get(target)
  if (!abi) {
    throw new ABINotFound(`Missing ABI for ${target}`)
  }
  return getContract(target, abi, config.web3Provider)
}
Example #6
Source File: index.ts    From snapshot-plugins with MIT License 5 votes vote down vote up
mustBeEthereumAddress = memoize((address: string) => {
  const startsWith0x = address?.startsWith('0x');
  const isValidAddress = isAddress(address);
  return startsWith0x && isValidAddress;
})
Example #7
Source File: index.ts    From snapshot-strategies with MIT License 5 votes vote down vote up
function isValidAddress(address: string): boolean {
  return (
    isAddress(address) &&
    address != '0x0000000000000000000000000000000000000000'
  );
}
Example #8
Source File: utils.ts    From hardhat-deploy with MIT License 5 votes vote down vote up
function transformNamedAccounts(
  configNamedAccounts: {[name: string]: any},
  chainIdGiven: string | number,
  accounts: string[],
  networkConfigName: string
): {
  namedAccounts: {[name: string]: string};
  unnamedAccounts: string[];
  unknownAccounts: string[];
  addressesToProtocol: {[address: string]: string};
} {
  const addressesToProtocol: {[address: string]: string} = {};
  const unknownAccountsDict: {[address: string]: boolean} = {};
  const knownAccountsDict: {[address: string]: boolean} = {};
  for (const account of accounts) {
    knownAccountsDict[account.toLowerCase()] = true;
  }
  const namedAccounts: {[name: string]: string} = {};
  const usedAccounts: {[address: string]: boolean} = {};
  // TODO transform into checksum  address
  if (configNamedAccounts) {
    const accountNames = Object.keys(configNamedAccounts);
    // eslint-disable-next-line no-inner-declarations
    function parseSpec(spec: any): string | undefined {
      let address: string | undefined;
      switch (typeof spec) {
        case 'string':
          // eslint-disable-next-line no-case-declarations
          const protocolSplit = spec.split('://');
          if (protocolSplit.length > 1) {
            if (protocolSplit[0].toLowerCase() === 'ledger') {
              address = protocolSplit[1];
              addressesToProtocol[address.toLowerCase()] =
                protocolSplit[0].toLowerCase();
              // knownAccountsDict[address.toLowerCase()] = true; // TODO ? this would prevent auto impersonation in fork/test
            } else if (protocolSplit[0].toLowerCase() === 'privatekey') {
              address = new Wallet(protocolSplit[1]).address;
              addressesToProtocol[address.toLowerCase()] =
                'privatekey://' + protocolSplit[1];
            } else {
              throw new Error(
                `unsupported protocol ${protocolSplit[0]}:// for named accounts`
              );
            }
          } else {
            if (spec.slice(0, 2).toLowerCase() === '0x') {
              if (!isAddress(spec)) {
                throw new Error(
                  `"${spec}" is not a valid address, if you used to put privateKey there, use the "privatekey://" prefix instead`
                );
              }
              address = spec;
            } else {
              address = parseSpec(configNamedAccounts[spec]);
            }
          }
          break;
        case 'number':
          if (accounts) {
            address = accounts[spec];
          }
          break;
        case 'undefined':
          break;
        case 'object':
          if (spec) {
            if (spec.type === 'object') {
              address = spec;
            } else {
              const newSpec = chainConfig(
                spec,
                chainIdGiven,
                networkConfigName
              );
              if (typeof newSpec !== 'undefined') {
                address = parseSpec(newSpec);
              }
            }
          }
          break;
      }
      if (address) {
        if (typeof address === 'string') {
          address = getAddress(address);
        }
      }
      return address;
    }

    for (const accountName of accountNames) {
      const spec = configNamedAccounts[accountName];
      const address = parseSpec(spec);
      if (address) {
        namedAccounts[accountName] = address;
        usedAccounts[address.toLowerCase()] = true;
        if (!knownAccountsDict[address.toLowerCase()]) {
          unknownAccountsDict[address.toLowerCase()] = true;
        }
      }
    }
  }
  const unnamedAccounts = [];
  for (const address of accounts) {
    if (!usedAccounts[address.toLowerCase()]) {
      unnamedAccounts.push(getAddress(address));
    }
  }
  return {
    namedAccounts,
    unnamedAccounts,
    unknownAccounts: Object.keys(unknownAccountsDict).map(getAddress),
    addressesToProtocol,
  };
}
Example #9
Source File: fetchThirdPartyList.ts    From pancake-toolkit with GNU General Public License v3.0 4 votes vote down vote up
fetchThirdPartyList = async (listName: string): Promise<void> => {
  try {
    const rawTokens = await getTokens(listName);
    const tokens = rawTokens.filter(({ address }) => !badTokens[listName].includes(address.toLowerCase()));
    const badDecimals = [];
    const badAddresses = [];
    const badSymbol = [];
    const badName = [];
    const duplicates = [];
    const invalidNameOrSymbol = [];

    const chunkSize = 200;
    const chunkArray = tokens.length >= chunkSize ? _.chunk(tokens, chunkSize) : [tokens];

    console.info("Total chunks: ", chunkArray.length);

    const realTokensDecimals = new Map();
    const realTokenSymbol = new Map();
    let currentChunk = 0;
    // eslint-disable-next-line no-restricted-syntax
    for (const chunk of chunkArray) {
      console.info(`Processing chunk ${++currentChunk} / ${chunkArray.length}`);
      const mapAddress = chunk.filter((token) => isAddress(token.address));
      badAddresses.push(...chunk.filter((token) => !isAddress(token.address)).map(({ address }) => address));
      const tokenInfoCalls = mapAddress.flatMap(({ address }) => [
        {
          address,
          name: "symbol",
        },
        {
          address,
          name: "name",
        },
        {
          address,
          name: "decimals",
        },
      ]);
      // console.info(
      //   "Debug problematic addresses",
      //   mapAddress.map(({ address }) => address)
      // );
      // eslint-disable-next-line no-await-in-loop
      const tokenInfoResponse = await multicallv2(erc20, tokenInfoCalls, { requireSuccess: false });
      mapAddress.forEach(({ address, name, symbol, decimals }, i) => {
        if (
          tokenInfoResponse[i * 3] === null ||
          tokenInfoResponse[i * 3 + 1] === null ||
          tokenInfoResponse[i * 3 + 2] === null
        ) {
          badAddresses.push(address);
          return;
        }
        const realSymbol = tokenInfoResponse[i * 3][0];
        const realName = tokenInfoResponse[i * 3 + 1][0];
        const realDecimals = tokenInfoResponse[i * 3 + 2][0];
        if (!decimals || decimals !== realDecimals) {
          badDecimals.push({ decimals, realDecimals, address });
        }
        if (!name || name !== realName) {
          badName.push({ name, realName, address });
        }
        if (!symbol || symbol !== realSymbol) {
          badSymbol.push({ name, realSymbol, address });
        }
        realTokenSymbol.set(address, realSymbol);
        realTokensDecimals.set(address, realDecimals);
      });
    }

    const sanitizedTokens = tokens
      .filter((token, index, array) => {
        const isNotDuplicate = array.findIndex((t) => t.address === token.address || t.name === token.name) === index;
        if (!isNotDuplicate) duplicates.push(token);
        const hasValidSymbol = /^[a-zA-Z0-9+\-%/$]+$/.test(realTokenSymbol.get(token.address));
        const symbolIsOk = realTokenSymbol.get(token.address)?.length > 0 && hasValidSymbol;
        if (!symbolIsOk) invalidNameOrSymbol.push(token.address);
        return isNotDuplicate && symbolIsOk && isAddress(token.address) && !badAddresses.includes(token.address);
      })
      .map((token) => {
        const checksummedAddress = getAddress(token.address);

        return {
          name: token.name,
          symbol: realTokenSymbol.get(token.address),
          address: checksummedAddress,
          chainId: token.chainId,
          decimals: realTokensDecimals.get(token.address),
          logoURI: token.logoURI,
        };
      });

    console.info(`About to save ${sanitizedTokens.length} tokens (original list has ${rawTokens.length})`);
    console.info(`Dropped: ${rawTokens.length - sanitizedTokens.length}`);
    console.info(`Bad decimals found: ${badDecimals.length}.`);
    console.info(`Bad names found: ${badName.length}.`);
    console.info(`Bad symbols found: ${badSymbol.length}.`);
    console.info(`Bad addresses found: ${badAddresses.length}`);
    console.info(`Duplicates found: ${duplicates.length}`);
    console.info(`Invalid name or symbosl: ${invalidNameOrSymbol.length}`);

    const tokenListPath = `${path.resolve()}/src/tokens/${listName}.json`;
    console.info("Saving updated list to ", tokenListPath);
    const stringifiedList = JSON.stringify(sanitizedTokens, null, 2);
    fs.writeFileSync(tokenListPath, stringifiedList);
  } catch (error) {
    console.error(`Error when fetching ${listName} list, error: ${error.message}`);
  }
}