@ordinalsbot/bitcoin-fee-estimator
Version:
A library for calculating Bitcoin transaction fees
811 lines (754 loc) • 22.3 kB
text/typescript
import { expect } from "chai";
import { estimateDirectInscriptionFee } from "../src/calculators/inscriptionTx";
import { InscriptionFile } from "../src/types";
describe("Real Inscription Transactions", () => {
const tolerancePct = 0.01; // 1%
it("6 file 9bb57cb66d79bae51cfa030118a23c4d0d5ac6c3807dc4ea49253b686a4ae88di0", () => {
// OB TRUE
// https://signet.ordinals.com/inscription/9bb57cb66d79bae51cfa030118a23c4d0d5ac6c3807dc4ea49253b686a4ae88di0
const files: InscriptionFile[] = [
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
];
const inscriptionInfo = {
feeRate: 1,
fee: 437,
files,
delegates: 0,
delegatesAverageSize: 33,
parents: 0,
parentsAverageSize: 33,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
inscriptionInfo.delegatesAverageSize,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("1 file 9b33bfa5d506776c3c940b28be196169d09516a33e648a86510885c42a6642c5i0", () => {
// OB TRUE
// https://signet.ordinals.com/inscription/9b33bfa5d506776c3c940b28be196169d09516a33e648a86510885c42a6642c5i0
const files: InscriptionFile[] = [
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
];
const inscriptionInfo = {
feeRate: 1,
fee: 169,
files,
delegates: 0,
parents: 0,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("1 file - 4 parents 3b7f1e53be3d8e1dfe5228c8cbe1f65f3d745d72a58df32d867cfd1bf22288a2i0", () => {
// OB TRUE
// https://signet.ordinals.com/inscription/3b7f1e53be3d8e1dfe5228c8cbe1f65f3d745d72a58df32d867cfd1bf22288a2i0
const files: InscriptionFile[] = [
{
size: 40_048,
mimeType: "image/jpeg",
},
];
const inscriptionInfo = {
feeRate: 1,
fee: 10_742,
files,
delegates: 0,
parents: 4,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("1 file - 1 parent 613b38e9c2cd6a9b197034f6dec9d2838bae5dbf07fe6c43986c2ef755058945i0", () => {
// OB TRUE
// https://signet.ordinals.com/inscription/613b38e9c2cd6a9b197034f6dec9d2838bae5dbf07fe6c43986c2ef755058945i0
const files: InscriptionFile[] = [
{
size: 13_336,
mimeType: "text/html;charset=utf-8",
},
];
const inscriptionInfo = {
feeRate: 1,
fee: 3649,
files,
delegates: 0,
parents: 1,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("1 file - 3 parents 6762c69938573509b333a559d2aa91209310b0888d1b08f229802124a5a675cbi0", () => {
// OB TRUE
// https://signet.ordinals.com/inscription/6762c69938573509b333a559d2aa91209310b0888d1b08f229802124a5a675cbi0
const files: InscriptionFile[] = [
{
size: 13_336,
mimeType: "text/html;charset=utf-8",
},
];
const inscriptionInfo = {
feeRate: 8,
fee: 31_216,
files,
delegates: 0,
parents: 3,
parentsAverageSize: 33,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
0,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("1 delegate - 1 parent d99f0faf3a0b53e6a811020392fc508bd2781e0f00b71834721a745ab3e6ca9bi0", () => {
// OB TRUE
// https://signet.ordinals.com/inscription/d99f0faf3a0b53e6a811020392fc508bd2781e0f00b71834721a745ab3e6ca9bi0
const files: InscriptionFile[] = [];
const inscriptionInfo = {
feeRate: 1,
fee: 297,
files,
delegates: 1,
parents: 1,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("7 delegates - 1 parent 4a0ff03fca8210176bbdf95b7adc8bab3a4916cab5a08a120e9a3497c1c07482", () => {
// OB TRUE
// https://mempool.space/signet/tx/4a0ff03fca8210176bbdf95b7adc8bab3a4916cab5a08a120e9a3497c1c07482
const files: InscriptionFile[] = [];
const inscriptionInfo = {
feeRate: 1,
fee: 674,
files,
delegates: 7,
delegatesAverageSize: 33,
parents: 1,
parentsAverageSize: 33,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
inscriptionInfo.delegatesAverageSize,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("10 delegates - 3 parents 5aee57340a59eff3149178125d86a5db320520c6ac221711f14250f7a994290b", () => {
// OB TRUE
// https://mempool.space/signet/tx/5aee57340a59eff3149178125d86a5db320520c6ac221711f14250f7a994290b
const files: InscriptionFile[] = [];
const inscriptionInfo = {
feeRate: 1,
fee: 1273,
files,
delegates: 10,
delegatesAverageSize: 33,
parents: 3,
parentsAverageSize: 33,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
inscriptionInfo.delegatesAverageSize,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("20 delegates - 9 parents b0fa0610bcba6aae5cc423e2d998037b5692ae46324b7dc541044b43c4581260", () => {
// OB TRUE
// https://mempool.space/signet/tx/b0fa0610bcba6aae5cc423e2d998037b5692ae46324b7dc541044b43c4581260
const files: InscriptionFile[] = [];
const inscriptionInfo = {
feeRate: 1,
fee: 3812,
files,
delegates: 20,
delegatesAverageSize: 32,
parents: 9,
parentsAverageSize: 33,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
inscriptionInfo.delegatesAverageSize,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("10 files b9c8af199fb93ff8d73f500aa519ee27413688e9420ec11145c76b93427ae49b", () => {
// OB TRUE
// https://mempool.space/signet/tx/b9c8af199fb93ff8d73f500aa519ee27413688e9420ec11145c76b93427ae49b
const files: InscriptionFile[] = [
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
];
const inscriptionInfo = {
feeRate: 1,
fee: 659,
files,
delegates: 0,
delegatesAverageSize: 32,
parents: 0,
parentsAverageSize: 33,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
inscriptionInfo.delegatesAverageSize,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("10 files - 2 parents 905f602006a63b87266736aac892c9130b9a64e1b896b301f8bc265aa7de2d45", () => {
// OB TRUE
// https://mempool.space/signet/tx/905f602006a63b87266736aac892c9130b9a64e1b896b301f8bc265aa7de2d45
const files: InscriptionFile[] = [
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
];
const inscriptionInfo = {
feeRate: 1,
fee: 1070,
files,
delegates: 0,
delegatesAverageSize: 32,
parents: 2,
parentsAverageSize: 33,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
inscriptionInfo.delegatesAverageSize,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("10 files and parents (legacy address) de8cdde58df62d8602448d733f18f859069d52a772cc8a87f2b632bdb6e81f4e", () => {
// OB TRUE
// https://mempool.space/signet/tx/de8cdde58df62d8602448d733f18f859069d52a772cc8a87f2b632bdb6e81f4e
const files: InscriptionFile[] = [
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
{
size: 4,
mimeType: "text/plain;charset=utf-8",
},
{
size: 10,
mimeType: "text/plain;charset=utf-8",
},
];
const inscriptionInfo = {
feeRate: 1,
fee: 967,
files,
delegates: 0,
delegatesAverageSize: 32,
parents: 2,
parentsAverageSize: 33,
receiverAddress: "mzkyV5pqT1TEMWrZVnCyT7cLK6huC2yFee",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
inscriptionInfo.delegatesAverageSize,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("20 delegates (legacy address) 1294bd365cf01696bf2ffb14b0e18933dbb2a52029e35706cd4db25b443452dc", () => {
// OB TRUE
// https://mempool.space/signet/tx/1294bd365cf01696bf2ffb14b0e18933dbb2a52029e35706cd4db25b443452dc
const files: InscriptionFile[] = [];
const inscriptionInfo = {
feeRate: 1,
fee: 1021,
files,
delegates: 20,
delegatesAverageSize: 32,
parents: 0,
parentsAverageSize: 33,
receiverAddress: "mzkyV5pqT1TEMWrZVnCyT7cLK6huC2yFee",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
inscriptionInfo.delegatesAverageSize,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("20 delegates - 3 parents (legacy address) 380f1568a766c74c98420a3d1140dcb4879336bc3fe83d40632130d0fa859f54", () => {
// OB TRUE
// https://mempool.space/signet/tx/380f1568a766c74c98420a3d1140dcb4879336bc3fe83d40632130d0fa859f54
const files: InscriptionFile[] = [];
const inscriptionInfo = {
feeRate: 1,
fee: 1859,
files,
delegates: 20,
delegatesAverageSize: 32,
parents: 3,
parentsAverageSize: 32,
receiverAddress: "mzkyV5pqT1TEMWrZVnCyT7cLK6huC2yFee",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
inscriptionInfo.delegatesAverageSize,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("1300 delegates (legacy address) 6560eba74bf313addcf9a92db730b7d092b874aaca8eddd3eb4062ef4fa791fc", () => {
// OB TRUE
// https://mempool.space/signet/tx/6560eba74bf313addcf9a92db730b7d092b874aaca8eddd3eb4062ef4fa791fc
const files: InscriptionFile[] = [];
const inscriptionInfo = {
feeRate: 1,
fee: 59238,
files,
delegates: 1300,
delegatesAverageSize: 32,
parents: 0,
parentsAverageSize: 32,
receiverAddress: "mzkyV5pqT1TEMWrZVnCyT7cLK6huC2yFee",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
inscriptionInfo.delegatesAverageSize,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("1300 delegates e7a6a1418af2a84209c4e7ea3b141d33cbe5e60d0e26a0421cf2e0c3a81f86ec", () => {
// OB TRUE
// https://mempool.space/signet/tx/e7a6a1418af2a84209c4e7ea3b141d33cbe5e60d0e26a0421cf2e0c3a81f86ec
const files: InscriptionFile[] = [];
const inscriptionInfo = {
feeRate: 1,
fee: 70938,
files,
delegates: 1300,
delegatesAverageSize: 33,
parents: 0,
parentsAverageSize: 32,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
inscriptionInfo.delegatesAverageSize,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
it("1 file with metadata - 3 parents 98823ed04ee145263d1e1c3c51395808dfda87457ea1753df07c812c409ca78b", () => {
// OB TRUE
// https://mempool.space/signet/tx/98823ed04ee145263d1e1c3c51395808dfda87457ea1753df07c812c409ca78b
const files: InscriptionFile[] = [
{
size: 1953,
mimeType: "image/png",
metadataSize: 26,
},
];
const inscriptionInfo = {
feeRate: 20,
fee: 20860,
files,
delegates: 0,
delegatesAverageSize: 33,
parents: 3,
parentsAverageSize: 33,
receiverAddress:
"tb1pgmdn0ppgsj5ug0a0pycdc24a84d2lyq9zd8v3eysk2wlyaythp4qlyxuwm",
};
const calculatedFee = estimateDirectInscriptionFee(
inscriptionInfo.feeRate,
inscriptionInfo.receiverAddress,
inscriptionInfo.files,
inscriptionInfo.delegates,
inscriptionInfo.parents,
inscriptionInfo.delegatesAverageSize,
inscriptionInfo.parentsAverageSize,
);
const tolerance = Math.ceil(inscriptionInfo.fee * tolerancePct);
expect(calculatedFee).closeTo(
inscriptionInfo.fee,
tolerance,
"fee mismatch",
);
expect(calculatedFee).gte(
inscriptionInfo.fee,
"Fee is lower than expected",
);
});
});