FuelLabs/fuels-ts · error · FuelError

INVALID_PUBLIC_KEY

INVALID_PUBLIC_KEY

Error message

Invalid Public Key: ${publicKey}.

What it means

Thrown by fromPublicKeyToB256() (packages/address/src/utils.ts:146) when isPublicKey(publicKey) returns false. A valid Fuel public key is exactly 130 characters: 0x followed by 128 hex digits (512 bits / 64 bytes). The function hashes the public key with SHA-256 to derive a B256 address. An invalid key cannot be hashed meaningfully, so the format is validated first.

Source

Thrown at packages/address/src/utils.ts:146

 * @param address - The EVM address to convert
 * @returns The B256 address
 *
 * @hidden
 */
export const fromEvmAddressToB256 = (address: string): B256Address =>
  padFirst12BytesOfEvmAddress(address);

/**
 * Converts a Public Key to a B256 address
 *
 * @param publicKey - The Public Key to convert
 * @returns The B256 address
 *
 * @hidden
 */
export const fromPublicKeyToB256 = (publicKey: string): B256Address => {
  if (!isPublicKey(publicKey)) {
    throw new FuelError(FuelError.CODES.INVALID_PUBLIC_KEY, `Invalid Public Key: ${publicKey}.`);
  }

  return hexlify(sha256(arrayify(publicKey)));
};

/**
 * Converts a dynamic input to a B256 address
 *
 * @param address - The dynamic input to convert
 * @returns The B256 address
 *
 * @hidden
 */
export const fromDynamicInputToB256 = (address: string | Address): B256Address => {
  if (typeof address !== 'string' && 'toB256' in address) {
    return address.toB256();
  }

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Validate with isPublicKey() before calling fromPublicKeyToB256().
  2. Ensure you are passing the uncompressed public key (512 bits / 130 hex chars including 0x), not a compressed key (256 bits).
  3. If deriving from a wallet, use the wallet's public key getter which returns the correct uncompressed format.

Example fix

// before
const addr = fromPublicKeyToB256(maybeCompressedKey);

// after
import { isPublicKey } from '@fuel-ts/address';
if (!isPublicKey(publicKey)) {
  throw new Error(`Expected uncompressed public key (0x + 128 hex), got length ${publicKey.length}`);
}
const addr = fromPublicKeyToB256(publicKey);
Defensive patterns

Strategy: type-guard

Validate before calling

import { isPublicKey } from '@fuel-ts/address';

if (!isPublicKey(publicKey)) {
  throw new Error(`Invalid public key: ${publicKey}. Must be 0x + 128 hex characters (uncompressed).`);
}
const b256 = fromPublicKeyToB256(publicKey);

Type guard

import { isPublicKey } from '@fuel-ts/address';

function isUncompressedPublicKey(value: string): boolean {
  return value.length === 130 && /(0x)[0-9a-f]{128}$/i.test(value);
}
// Use isPublicKey() directly for the guard

Try / catch

try {
  const b256 = fromPublicKeyToB256(publicKey);
} catch (e) {
  if (e instanceof FuelError && e.code === 'invalid-public-key') {
    // key is not 0x + 128 hex; check for compressed key or missing prefix
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling fromPublicKeyToB256() with a string that is not 130 characters matching 0x + 128 hex digits — e.g. a compressed public key (66 chars), a private key, a B256 address, or a key missing the 0x prefix.

Common situations: Deriving a Fuel address from an uncompressed secp256k1 public key; accidentally passing a compressed key or a B256 address instead; key material truncated or hex-encoded incorrectly (e.g. with a 0X uppercase prefix or whitespace).

Related errors


AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12). Data as JSON: /api/errors/d996eab310001703. Report an issue: GitHub.