import { Hex } from "viem" import predictOrangeKitAddress, { InvalidTruncatedBitcoinAddressLengthError, predictAddressFromTruncatedBitcoinAddress, } from "./predictOrangeKitAddress" type BaseTestData = { output: Hex | Error | string description: string } type TruncatedAddressTestData = BaseTestData & { input: Hex } type BitcoinAddressTestData = BaseTestData & { input: [string, string | undefined] } /* The following test data was generated by running input values through the `predictAddress` on-chain function. It covers a wide range of edge cases and patterns characteristic to hexadecimal values representing truncated addresses including throwing errors for invalid inputs. */ const passTestDataWithTruncatedAddressInput: TruncatedAddressTestData[] = [ { description: "zero value", input: "0x0000000000000000000000000000000000000000", output: "0xd84C120D84CC795F9b5649594B916A961C64f387", }, { description: "maximum possible value", input: "0xffffffffffffffffffffffffffffffffffffffff", output: "0x1Ae9407f0FA2f165cC28767750bBCd0219540c62", }, { description: "alternating zero and non-zero bytes", input: "0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", output: "0x16608714812c0FB4Bb94cCb4A2c27BEE95E32432", }, { description: "lowercase hexadecimal characters", input: "0x1234567890abcdef1234567890abcdef12345678", output: "0xc6Dc4b63f691de9ec6E495Fe3b1207C1CABa5370", }, { description: "uppercase hexadecimal characters", input: "0x1234567890ABCDEF1234567890ABCDEF12345678", output: "0xc6Dc4b63f691de9ec6E495Fe3b1207C1CABa5370", }, { description: "only the last byte set (leading zeros)", input: "0x00000000000000000000000000000000000000ff", output: "0xF3cD2c9660B19F68d9F4CD99Be10C057ed3A766A", }, { description: "all bits set in the first 32 bits (trailing zeros)", input: "0xffffffff00000000000000000000000000000000", output: "0xC5d7e7a75527302521aeCfE6Acb38806c49ABF1A", }, ] const failTestDataWithTruncatedAddressInput: TruncatedAddressTestData[] = [ { description: "empty string", input: "0x", output: InvalidTruncatedBitcoinAddressLengthError, }, { description: "too short string", input: `0x${"0".repeat(39)}`, output: InvalidTruncatedBitcoinAddressLengthError, }, { description: "too long string", input: `0x${"0".repeat(41)}`, output: InvalidTruncatedBitcoinAddressLengthError, }, ] /** * The following test data was copied from `predictOrangeKitAddress` integration tests */ const passTestDataWithBitcoinAddressInput: BitcoinAddressTestData[] = [ { description: "valid Bitcoin address", input: [ "mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB", "04b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2d0602636b20701e3620ced9467f9e334bdbf9a265b87b8e30d7e4e0a94451f7b98d70177f1951a", ], output: "0x6083Bde64CCBF08470a1a0dAa9a0281B4951be7C", }, ] const failTestDataWithBitcoinAddressInput: BitcoinAddressTestData[] = [ { description: "invalid Bitcoin address", input: [ "xv4rnyY3xxxxjcxxxxMLKxxxxicCtHUtFB", passTestDataWithBitcoinAddressInput[0].input[1], ], output: "Unsupported address. Supported addresses: P2WPKH, P2PKH, P2SH_P2WPKH", }, { description: "invalid Bitcoin address (too short)", input: ["bc1x", undefined], output: "bc1x too short", }, ] describe("predictAddressFromTruncatedBitcoinAddress", () => { it.each(passTestDataWithTruncatedAddressInput)( "should predict address for input of $description", ({ input, output }) => { expect(predictAddressFromTruncatedBitcoinAddress(input)).toBe(output) }, ) it.each(failTestDataWithTruncatedAddressInput)( "should throw error for input of $description", ({ input, output }) => { expect(() => predictAddressFromTruncatedBitcoinAddress(input)).toThrow( output, ) }, ) }) describe("predictOrangeKitAddress", () => { it.each([passTestDataWithBitcoinAddressInput])( "should predict address for input of $description", ({ input, output }) => { expect(predictOrangeKitAddress(...input)).toBe(output) }, ) it.each(failTestDataWithBitcoinAddressInput)( "should throw error for input of $description", ({ input, output }) => { expect(() => predictOrangeKitAddress(...input)).toThrow(output) }, ) }) // eslint-disable-next-line import/prefer-default-export export const predictAddressTestData = { passTestDataWithTruncatedAddressInput, failTestDataWithTruncatedAddressInput, passTestDataWithBitcoinAddressInput, failTestDataWithBitcoinAddressInput, }