PHP WebShell

Текущая директория: /opt/BitGoJS/modules/sdk-coin-xtz/test/unit

Просмотр файла: util.ts

import assert from 'assert';
import should from 'should';

import {
  defaultDataToSign,
  defaultKeyPairFromPrv,
  defaultKeyPairFromPub,
  signedSerializedOriginationTransaction,
  validDataToSign,
} from '../resources';
import { XtzLib } from '../../src';
import { HashType } from '../../src/lib/iface';

describe('XTZ util library', function () {
  describe('address', function () {
    it('should validate addresses', function () {
      const validAddresses = [
        'tz1aWXP237BLwNHJcCD4b3DutCevhqq2T1Z9',
        'tz2SHdGxFGhs68wYNC4hEqxbWARxp2J4mVxv',
        'tz3gN8NTLNLJg5KRsUU47NHNVHbdhcFXjjaB',
        'KT1EGbAxguaWQFkV3Egb2Z1r933MWuEYyrJS',
      ];

      for (const address of validAddresses) {
        XtzLib.Utils.isValidAddress(address).should.be.true();
      }
    });

    it('should fail to validate invalid addresses', function () {
      const invalidAddresses = [
        'tz4aWXP237BLwNHJcCD4b3DutCevhqq2T1Z9',
        'xtz2SHdGxFGhs68wYNC4hEqxbWARxp2J4mVxv',
        'KT2EGbAxguaWQFkV3Egb2Z1r933MWuEYyrJS',
        'abc',
      ];

      for (const address of invalidAddresses) {
        should.doesNotThrow(() => XtzLib.Utils.isValidAddress(address));
        XtzLib.Utils.isValidAddress(address).should.be.false();
      }
    });
  });

  describe('block hash', function () {
    it('should validate block hashes', function () {
      const validHashes = [
        'BKoifs5gGffAzuRBcg3ygxbLdrCXyDDS1ALvMG8SFYWahzoYMku',
        'BL4oxWAkozJ3mJHwVFQqga5dQMBi8kBCPAQyBKgF78z7SQT1AvN',
        'BL29n92KHaarq1r7XjwTFotzCpxq7LtXMc9bF2qD9Qt26ZTYQia',
      ];

      for (const hash of validHashes) {
        XtzLib.Utils.isValidBlockHash(hash).should.be.true();
      }
    });

    it('should fail to validate invalid block hashes', function () {
      const invalidHashes = [
        'AKoifs5gGffAzuRBcg3ygxbLdrCXyDDS1ALvMG8SFYWahzoYMku',
        'BKoifs5gGffAzuRBcg3ygxbLdrCXyDDS1ALvMG8SFYWahzoYMku1111111111',
        'invalid',
      ];

      for (const hash of invalidHashes) {
        XtzLib.Utils.isValidBlockHash(hash).should.be.false();
      }
    });
  });

  describe('transaction hash', function () {
    it('should validate tx hashes', function () {
      const validHashes = [
        'opUmZNMueryYFxTbzzocS7K4dzs3NmgKqhhr9TkcftszDDnoRVu',
        'ookyzxsYF7vyTeDzsgs58XJ4PXuvBkK8wWqZJ4EoRS6RWQb4Y9P',
        'ooXQoUX32szALRvgzD2TDzeRPXtPfmfqwoehPaK5khbrBiMAtSw',
      ];

      for (const hash of validHashes) {
        XtzLib.Utils.isValidTransactionHash(hash).should.be.true();
      }
    });

    it('should fail to validate invalid tx hashes', function () {
      const invalidHashes = [
        'lpUmZNMueryYFxTbzzocS7K4dzs3NmgKqhhr9TkcftszDDnoRVu',
        'opUmZNMueryYFxTbzzocS7K4dzs3NmgKqhhr9TkcftszDDnoRVu1111111111',
        'invalid',
      ];

      for (const hash of invalidHashes) {
        XtzLib.Utils.isValidTransactionHash(hash).should.be.false();
      }
    });

    it('should calculate the transaction hash', async function () {
      const operationId = await XtzLib.Utils.calculateTransactionId(signedSerializedOriginationTransaction);
      operationId.should.equal('opPsNbm7EcqPyryBDDR28BjdthnriktK8TbMvpwc9r4NwmvToYP');
    });

    it('should calculate the originated account address', async function () {
      const accountAddress = await XtzLib.Utils.calculateOriginatedAddress(
        'opPsNbm7EcqPyryBDDR28BjdthnriktK8TbMvpwc9r4NwmvToYP',
        0
      );
      accountAddress.should.equal('KT1LJvp55fbdNwbisJFign9wA4cPgq9T9oc4');
    });
  });

  describe('sign', function () {
    it('should produce a valid signature', async function () {
      const signatures = await XtzLib.Utils.sign(defaultKeyPairFromPrv, defaultDataToSign);
      signatures.bytes.should.equal(
        '0507070a000000160196369c90625575ba44594b23794832a9337f7a2d0007070000050502000000320320053d036d0743035d0a00000015006b5ddaef3fb5d7c151cfb36fbe43a7a066777394031e0743036a0001034f034d031b'
      );
      signatures.prefixSig.should.equal(
        'spsig19yWAc5nBpGmNCWdvEWHnpJXEiTqZjhNgWwWa1Lz6kVgakb7qCPj9z6G6LLEFWmsmNcPCZYseERVDUXh99N7wqDppcDKQM'
      );
      signatures.sbytes.should.equal(
        '0507070a000000160196369c90625575ba44594b23794832a9337f7a2d0007070000050502000000320320053d036d0743035d0a00000015006b5ddaef3fb5d7c151cfb36fbe43a7a066777394031e0743036a0001034f034d031b1fd49502ba8dc7adb01716093abe715d1eef87f47a88d8ec104fcc1d6baca7ba06cc2ced6c5baa880d6045b44be926d63bc3aeb3b9124f3b32ac6d9c63584fe5'
      );
      signatures.sig.should.equal(
        'sigS9pqYUXiUJcz2Wsx5x98ud9KtgGVg4gCwpBoDBgHrZy9gwJedKMCrcQPxm9C7i1gesETbhFD6Gm8BpadGgd2cgiGoQbiY'
      );
    });

    it('should produce a valid signature with watermark', async function () {
      const signatures = await XtzLib.Utils.sign(defaultKeyPairFromPrv, defaultDataToSign, new Uint8Array());
      signatures.bytes.should.equal(
        '0507070a000000160196369c90625575ba44594b23794832a9337f7a2d0007070000050502000000320320053d036d0743035d0a00000015006b5ddaef3fb5d7c151cfb36fbe43a7a066777394031e0743036a0001034f034d031b'
      );
      signatures.prefixSig.should.equal(
        'spsig1DWTuXdgUg2t64PLRfaapsYejCoCVVkqy2Zjv41Zirt7MjoqSfBnP38qoAg3SWicfQNiG25yMqGYge4jrfrwv9H8hRKDyY'
      );
      signatures.sbytes.should.equal(
        '0507070a000000160196369c90625575ba44594b23794832a9337f7a2d0007070000050502000000320320053d036d0743035d0a00000015006b5ddaef3fb5d7c151cfb36fbe43a7a066777394031e0743036a0001034f034d031b3ad76776913e2c0cfe827b572c417b73a14debcf9e5db726ce9b10aa4bea6aa1173b313ff67eb9bdfdcf9a753178e6ac78ac5f53aef8bcca6d56706f5c3fb01f'
      );
      signatures.sig.should.equal(
        'sigVgnaU2S1L4jhtPaTX2SAxsGpP1dRS89VTSR9FrFuxxPvgA2G67QRuez6o6xP7ekagdZX4ELvh7pbMMdLoBSzvk2AVyQpk'
      );
    });

    it('should validate a signature belongs to a public key for a string message', async function () {
      const message = 'helloworld';
      const messageHex = Buffer.from(message).toString('hex');
      const signatures = await XtzLib.Utils.sign(defaultKeyPairFromPrv, messageHex, new Uint8Array(0));
      const result = await XtzLib.Utils.verifySignature(
        messageHex,
        defaultKeyPairFromPub.getKeys().pub,
        signatures.sig,
        new Uint8Array(0)
      );
      result.should.be.true();
    });

    it('should validate a signature belongs to a public key for dataToSign', async function () {
      const messageHex = Buffer.from(defaultDataToSign).toString('hex');
      const signatures = await XtzLib.Utils.sign(defaultKeyPairFromPrv, messageHex, new Uint8Array(0));
      const result = await XtzLib.Utils.verifySignature(
        messageHex,
        defaultKeyPairFromPub.getKeys().pub,
        signatures.sig,
        new Uint8Array(0)
      );
      result.should.be.true();
    });

    it('should fail to validate a signature with the wrong watermark', async function () {
      const messageHex = Buffer.from(defaultDataToSign).toString('hex');
      const signatures = await XtzLib.Utils.sign(defaultKeyPairFromPrv, messageHex);
      const result = await XtzLib.Utils.verifySignature(
        messageHex,
        defaultKeyPairFromPub.getKeys().pub,
        signatures.sig,
        new Uint8Array(3)
      );
      result.should.be.false();
    });

    it('should fail to validate a signature with the wrong public key', async function () {
      const messageHex = Buffer.from(defaultDataToSign).toString('hex');
      const signatures = await XtzLib.Utils.sign(defaultKeyPairFromPrv, messageHex);
      const result = await XtzLib.Utils.verifySignature(
        messageHex,
        'sppk7d2ztzbrLdBaTB7yzaWRkPfcWGsrNQNJdkBE9bCTSSzekLNzpvf',
        signatures.sig
      );
      result.should.be.false();
    });

    it('should fail to validate a signature with the wrong message', async function () {
      const messageHex = Buffer.from(defaultDataToSign).toString('hex');
      const signatures = await XtzLib.Utils.sign(defaultKeyPairFromPrv, messageHex);
      const secondMessageHex = Buffer.from('helloWorld').toString('hex');
      const result = await XtzLib.Utils.verifySignature(
        secondMessageHex,
        defaultKeyPairFromPub.getKeys().pub,
        signatures.sig
      );
      result.should.be.false();
    });

    it('should fail if the key pair does not have the private key', async function () {
      await XtzLib.Utils.sign(defaultKeyPairFromPub, defaultDataToSign).should.be.rejectedWith(
        new RegExp('Missing private key')
      );
    });
  });

  describe('generateDataToSign', function () {
    it('should build transfer data to sign', function () {
      const dataToSign = XtzLib.Utils.generateDataToSign(
        'KT1NH2M23xovhw7uwWVuoGTYxykeCcVfSqhL',
        'tz2PtJ9zgEgFVTRqy6GXsst54tH3ksEnYvvS',
        '100',
        '0'
      );
      JSON.stringify(dataToSign).should.equal(JSON.stringify(validDataToSign));
    });

    it('should fail if the contract address has the wrong format', function () {
      assert.throws(
        () =>
          XtzLib.Utils.generateDataToSign(
            'tz2PtJ9zgEgFVTRqy6GXsst54tH3ksEnYvvS',
            'tz2PtJ9zgEgFVTRqy6GXsst54tH3ksEnYvvS',
            '0',
            '0'
          ),
        new RegExp('Invalid contract address')
      );
    });

    it('should fail if the destination address has the wrong format', function () {
      assert.throws(
        () => XtzLib.Utils.generateDataToSign('KT1NH2M23xovhw7uwWVuoGTYxykeCcVfSqhL', 'abc', '0', '0'),
        new RegExp('Invalid destination address')
      );
    });
  });

  describe('signature', function () {
    it('should validate signature', function () {
      const validSignatures = [
        'sigVgnaU2S1L4jhtPaTX2SAxsGpP1dRS89VTSR9FrFuxxPvgA2G67QRuez6o6xP7ekagdZX4ELvh7pbMMdLoBSzvk2AVyQpk',
        'spsig1DWTuXdgUg2t64PLRfaapsYejCoCVVkqy2Zjv41Zirt7MjoqSfBnP38qoAg3SWicfQNiG25yMqGYge4jrfrwv9H8hRKDyY',
        'sigS9pqYUXiUJcz2Wsx5x98ud9KtgGVg4gCwpBoDBgHrZy9gwJedKMCrcQPxm9C7i1gesETbhFD6Gm8BpadGgd2cgiGoQbiY',
        'spsig19yWAc5nBpGmNCWdvEWHnpJXEiTqZjhNgWwWa1Lz6kVgakb7qCPj9z6G6LLEFWmsmNcPCZYseERVDUXh99N7wqDppcDKQM',
      ];

      for (const hash of validSignatures) {
        XtzLib.Utils.isValidSignature(hash).should.be.true();
      }
    });

    it('should fail to validate invalid signature', function () {
      const invalidHashes = [
        'sigS9pqYUXiUJcz2Wsx5x98ud9KtgGVg4gCwpBoDBgHrZ',
        'sig',
        'BKoifs5gGffAzuRBcg3ygxbLdrCXyDDS1ALvMG8SFYWahzoYMku1111111111',
        'invalid',
      ];

      for (const hash of invalidHashes) {
        XtzLib.Utils.isValidSignature(hash).should.be.false();
      }
    });
  });

  describe('decodeKey', function () {
    it('should decode the key', function () {
      const validKeys = [['spsk2cbiVsAvpGKmau9XcMscL3NRwjkyT575N5AyAofcoj41x6g6TL', XtzLib.Utils.hashTypes.spsk]];

      for (const data of validKeys) {
        XtzLib.Utils.decodeKey(data[0] as string, data[1] as HashType)
          .toString('hex')
          .should.equal('9cc0aaa9ef687e70f7780e60de08d7a443488a9cf8e1ebe9689118763376c07c');
      }
    });

    it('should fail to decode an invalid key', function () {
      const invalidKeys = [
        [
          'sigVgnaU2S1L4jhtPaTX2SAxsGpP1dRS89VTSR9FrFuxxPvgA2G67QRuez6o6xP7ekagdZX4ELvh7pbMMdLoBSzvk2AVyQpk',
          XtzLib.Utils.hashTypes.tz1,
        ],
        ['sppk', XtzLib.Utils.hashTypes.sppk],
      ];

      for (const data of invalidKeys) {
        assert.throws(
          () => XtzLib.Utils.decodeKey(data[0] as string, data[1] as HashType),
          new RegExp('Unsupported private key')
        );
      }
    });
  });
});

Выполнить команду


Для локальной разработки. Не используйте в интернете!