UNPKG

@btc-vision/transaction

Version:

OPNet transaction library allows you to create and sign transactions for the OPNet network.

103 lines (87 loc) 4.29 kB
import { describe, expect, it } from 'vitest'; import { stringToBuffer } from '../build/utils/StringToBuffer.js'; describe('Hex prefix stripping (anchored replace)', () => { describe('stringToBuffer', () => { it('should strip leading 0x prefix from hex string', () => { const result = stringToBuffer('0xabcdef'); expect(result).toBeInstanceOf(Uint8Array); expect(result.length).toBe(3); expect(result[0]).toBe(0xab); expect(result[1]).toBe(0xcd); expect(result[2]).toBe(0xef); }); it('should pass through hex string without 0x prefix', () => { const result = stringToBuffer('abcdef'); expect(result).toBeInstanceOf(Uint8Array); expect(result.length).toBe(3); expect(result[0]).toBe(0xab); }); it('should NOT strip 0x from middle of hex data', () => { // "0xdead0000beef" has leading 0x -> strip it -> "dead0000beef" -> 6 bytes const result = stringToBuffer('0xdead0000beef'); expect(result.length).toBe(6); expect(result[0]).toBe(0xde); expect(result[1]).toBe(0xad); expect(result[2]).toBe(0x00); expect(result[3]).toBe(0x00); expect(result[4]).toBe(0xbe); expect(result[5]).toBe(0xef); }); it('should handle 32-byte hash with 0x prefix', () => { const hash = '0x' + 'ab'.repeat(32); const result = stringToBuffer(hash); expect(result.length).toBe(32); expect(result.every((b) => b === 0xab)).toBe(true); }); it('should handle 32-byte hash without 0x prefix', () => { const hash = 'ab'.repeat(32); const result = stringToBuffer(hash); expect(result.length).toBe(32); expect(result.every((b) => b === 0xab)).toBe(true); }); it('should handle empty string after prefix strip', () => { expect(() => stringToBuffer('0x')).not.toThrow(); }); it('should preserve data when hex naturally contains 0x byte sequence', () => { // A hash where bytes 0x30 0x78 (ASCII '0x') appear naturally // e.g. position 4-5 of this hash: "aabbccdd3078eeff..." // Old code: .replace('0x','') would strip '30' and '78' -> corrupt // New code: no leading 0x, pass through unchanged const hexWithNatural0x = 'aabbccdd3078eeff'; const result = stringToBuffer(hexWithNatural0x); expect(result.length).toBe(8); expect(result[4]).toBe(0x30); // '0' in ASCII expect(result[5]).toBe(0x78); // 'x' in ASCII }); }); describe('anchored vs unanchored behavior difference', () => { it('unanchored replace corrupts base64 with natural 0x', () => { // Prove the old behavior was broken const base64 = '7b35xyUK7jCoKcgiOmUQ7OGMOSO0xRjQycTYCOxe/Lw='; const oldBroken = base64.replace('0x', ''); const newFixed = base64.startsWith('0x') ? base64.slice(2) : base64; // Old strips 2 chars from middle expect(oldBroken).not.toBe(base64); expect(oldBroken.length).toBe(base64.length - 2); // New preserves the string (no leading 0x) expect(newFixed).toBe(base64); // atob fails on corrupted string expect(() => atob(oldBroken)).toThrow(); expect(() => atob(newFixed)).not.toThrow(); }); it('both methods work correctly for actual 0x-prefixed hex', () => { const hex = '0xdeadbeef'; const oldResult = hex.replace('0x', ''); const newResult = hex.startsWith('0x') ? hex.slice(2) : hex; expect(oldResult).toBe('deadbeef'); expect(newResult).toBe('deadbeef'); }); it('both methods work for strings without 0x', () => { const plain = 'deadbeef'; const oldResult = plain.replace('0x', ''); const newResult = plain.startsWith('0x') ? plain.slice(2) : plain; expect(oldResult).toBe('deadbeef'); expect(newResult).toBe('deadbeef'); }); }); });