# src/publickey.js

    // @flow

    import BN from 'bn.js';
    import bs58 from 'bs58';

    /**
     * A public key
     */
    export class PublicKey {
      _bn: BN;

      /**
       * Create a new PublicKey object
       */
      constructor(value: number | string | Buffer | Array<number>) {
        if (typeof value === 'string') {
          // hexadecimal number
          if (value.startsWith('0x')) {
            this._bn = new BN(value.substring(2), 16);
          } else {
            // assume base 58 encoding by default
            const decoded = bs58.decode(value);
            if (decoded.length != 32) {
              throw new Error(`Invalid public key input`);
            }
            this._bn = new BN(decoded);
          }
        } else {
          this._bn = new BN(value);
        }

        if (this._bn.byteLength() > 32) {
          throw new Error(`Invalid public key input`);
        }
      }

      /**
       * Checks if the provided object is a PublicKey
       */
      static isPublicKey(o: Object): boolean {
        return o instanceof PublicKey;
      }

      /**
       * Checks if two publicKeys are equal
       */
      equals(publicKey: PublicKey): boolean {
        return this._bn.eq(publicKey._bn);
      }

      /**
       * Return the base-58 representation of the public key
       */
      toBase58(): string {
        return bs58.encode(this.toBuffer());
      }

      /**
       * Return the Buffer representation of the public key
       */
      toBuffer(): Buffer {
        const b = this._bn.toArrayLike(Buffer);
        if (b.length === 32) {
          return b;
        }

        const zeroPad = Buffer.alloc(32);
        b.copy(zeroPad, 32 - b.length);
        return zeroPad;
      }

      /**
       * Returns a string representation of the public key
       */
      toString(): string {
        return this.toBase58();
      }
    }