@ordinalsbot/bitcoin-fee-estimator
Version:
A library for calculating Bitcoin transaction fees
193 lines (170 loc) • 6.45 kB
text/typescript
import { expect } from "chai";
import {
detectOutputScriptType,
getScriptTypeFromAddress,
} from "../src/common";
import { ScriptType } from "../src/types";
describe("getScriptTypeFromAddress", () => {
describe("Mainnet addresses", () => {
it("should detect P2PKH addresses (starting with 1)", () => {
expect(
getScriptTypeFromAddress("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"),
).to.equal(ScriptType.P2PKH);
expect(
getScriptTypeFromAddress("12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX"),
).to.equal(ScriptType.P2PKH);
});
it("should detect P2SH addresses (starting with 3)", () => {
expect(
getScriptTypeFromAddress("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy"),
).to.equal(ScriptType.P2SH);
expect(
getScriptTypeFromAddress("3FZbgi29cpjq2GjdwV8eyHuJJnkLtktZc5"),
).to.equal(ScriptType.P2SH);
});
it("should detect P2WPKH addresses (starting with bc1q)", () => {
expect(
getScriptTypeFromAddress("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"),
).to.equal(ScriptType.P2WPKH);
});
it("should detect P2WSH addresses (starting with bc1q)", () => {
expect(
getScriptTypeFromAddress(
"bc1qp3eqzeuz97rh3nnhapy5lxjguueazurqdezd8rjakcwjscp6dwcsqckypc",
),
).to.equal(ScriptType.P2WSH);
});
it("should detect P2TR addresses (starting with bc1p)", () => {
expect(
getScriptTypeFromAddress(
"bc1pp4djkw70g7s27hhj7j3hddfca3hgzsay66xhpw2mt26znqpdds8sw7lxz2",
),
).to.equal(ScriptType.P2TR);
});
});
describe("Testnet addresses", () => {
it("should detect testnet P2PKH addresses (starting with m or n)", () => {
expect(
getScriptTypeFromAddress("mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJRfn"),
).to.equal(ScriptType.P2PKH);
expect(
getScriptTypeFromAddress("n4f7rXQcbpoYFUbTenRZCaqJ1fhgoJxik3"),
).to.equal(ScriptType.P2PKH);
});
it("should detect testnet P2SH addresses (starting with 2)", () => {
expect(
getScriptTypeFromAddress("2NByHN6A8QYkBATzxf4pRGbCSHD5CEN2TRu"),
).to.equal(ScriptType.P2SH);
});
it("should detect testnet P2WPKH addresses (starting with tb1q)", () => {
expect(
getScriptTypeFromAddress("tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx"),
).to.equal(ScriptType.P2WPKH);
});
it("should detect testnet P2WSH addresses (starting with tb1q)", () => {
expect(
getScriptTypeFromAddress(
"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
),
).to.equal(ScriptType.P2WSH);
});
it("should detect testnet P2TR addresses (starting with tb1p)", () => {
expect(
getScriptTypeFromAddress(
"tb1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq47zagq",
),
).to.equal(ScriptType.P2TR);
});
});
describe("Invalid addresses", () => {
it("should return UNKNOWN for invalid addresses", () => {
expect(getScriptTypeFromAddress("")).to.equal(ScriptType.UNKNOWN);
expect(getScriptTypeFromAddress("not an address")).to.equal(
ScriptType.UNKNOWN,
);
expect(getScriptTypeFromAddress("bc1invalid")).to.equal(
ScriptType.UNKNOWN,
);
expect(getScriptTypeFromAddress("1111111111111111111114")).to.equal(
ScriptType.UNKNOWN,
); // Invalid checksum
});
it("should return UNKNOWN for non-string inputs", () => {
expect(getScriptTypeFromAddress(null as never)).to.equal(
ScriptType.UNKNOWN,
);
expect(getScriptTypeFromAddress(undefined as never)).to.equal(
ScriptType.UNKNOWN,
);
expect(getScriptTypeFromAddress(123 as never)).to.equal(
ScriptType.UNKNOWN,
);
});
});
describe("Edge cases", () => {
it("should return UNKNOWN for P2PK addresses (no standard address format)", () => {
// P2PK doesn't have a standard address format
expect(getScriptTypeFromAddress("04somepublickey")).to.equal(
ScriptType.UNKNOWN,
);
});
it("should return UNKNOWN for OP_RETURN (no address format)", () => {
// OP_RETURN doesn't have an address format
expect(getScriptTypeFromAddress("OP_RETURN")).to.equal(
ScriptType.UNKNOWN,
);
});
});
});
describe("Real Signet Transactions", () => {
it("should return correct script type", () => {
const P2PK =
"41049464205950188c29d377eebca6535e0f3699ce4069ecd77ffebfbd0bcf95e3c134cb7d2742d800a12df41413a09ef87a80516353a2f0a280547bb5512dc03da8ac";
expect(detectOutputScriptType(Buffer.from(P2PK, "hex"))).eq(
ScriptType.P2PK,
);
const P2TR =
"51200f0c8db753acbd17343a39c2f3f4e35e4be6da749f9e35137ab220e7b238a667";
expect(detectOutputScriptType(Buffer.from(P2TR, "hex"))).eq(
ScriptType.P2TR,
);
const P2PKH = "76a91455ae51684c43435da751ac8d2173b2652eb6410588ac";
expect(detectOutputScriptType(Buffer.from(P2PKH, "hex"))).eq(
ScriptType.P2PKH,
);
const P2SH = "a914748284390f9e263a4b766a75d0633c50426eb87587";
expect(detectOutputScriptType(Buffer.from(P2SH, "hex"))).eq(
ScriptType.P2SH,
);
const P2WPKH = "0014841b80d2cc75f5345c482af96294d04fdd66b2b7";
expect(detectOutputScriptType(Buffer.from(P2WPKH, "hex"))).eq(
ScriptType.P2WPKH,
);
const P2WSH =
"002065f91a53cb7120057db3d378bd0f7d944167d43a7dcbff15d6afc4823f1d3ed3";
expect(detectOutputScriptType(Buffer.from(P2WSH, "hex"))).eq(
ScriptType.P2WSH,
);
const OP_RETURN = "6a0b68656c6c6f20776f726c64";
expect(detectOutputScriptType(Buffer.from(OP_RETURN, "hex"))).eq(
ScriptType.OP_RETURN,
);
const P2SH_P2WPKH_SCRIPT = "a9144733f37cf4db86fbc2efed2500b4f4e49f31202387";
const P2SH_P2WPKH_REDEEM = "0014841b80d2cc75f5345c482af96294d04fdd66b2b7";
expect(
detectOutputScriptType(
Buffer.from(P2SH_P2WPKH_SCRIPT, "hex"),
Buffer.from(P2SH_P2WPKH_REDEEM, "hex"),
),
).eq(ScriptType.P2SH_P2WPKH);
const P2SH_P2WSH_SCRIPT = "a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a187";
const P2SH_P2WSH_REDEEM =
"002065f91a53cb7120057db3d378bd0f7d944167d43a7dcbff15d6afc4823f1d3ed3";
expect(
detectOutputScriptType(
Buffer.from(P2SH_P2WSH_SCRIPT, "hex"),
Buffer.from(P2SH_P2WSH_REDEEM, "hex"),
),
).eq(ScriptType.P2SH_P2WSH);
});
});