diff options
| author | Adam Soltys <[email protected]> | 2026-03-02 22:50:58 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-03-02 22:51:02 -0800 |
| commit | c7300714c57652e68fcadcdbcfcce3df8dd7d37b (patch) | |
| tree | 84bee888a8f3173257c6d2aa9670d41498f50c63 /lib/p2a.ts | |
| parent | 58e7f32f48c2fb094196f44f4c59a8975e5f93a9 (diff) | |
| download | coinos-server-c7300714c57652e68fcadcdbcfcce3df8dd7d37b.tar.gz coinos-server-c7300714c57652e68fcadcdbcfcce3df8dd7d37b.zip | |
fee bumping
Diffstat (limited to 'lib/p2a.ts')
| -rw-r--r-- | lib/p2a.ts | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/p2a.ts b/lib/p2a.ts new file mode 100644 index 00000000..6e256f20 --- /dev/null +++ b/lib/p2a.ts @@ -0,0 +1,54 @@ +import config from "$config"; +import { bech32m } from "@scure/base"; + +export const P2A_VALUE = 240; +export const P2A_SCRIPT = "51024e73"; // OP_1 OP_PUSHBYTES_2 0x4e73 +export const CHILD_VSIZE = 152; + +const P2A_WITNESS_PROGRAM = new Uint8Array([0x4e, 0x73]); +const P2A_WITNESS_VERSION = 1; + +const P2A_ADDRESSES: Record<string, string> = { + mainnet: "bc1pfeessrawgf", + testnet: "tb1pfeessrawgf", + signet: "tb1pfeessrawgf", + regtest: "bcrt1pfeessrawgf", +}; + +const BECH32M_PREFIXES: Record<string, string> = { + mainnet: "bc", + testnet: "tb", + signet: "tb", + regtest: "bcrt", +}; + +function verifyP2AAddresses() { + for (const [network, expected] of Object.entries(P2A_ADDRESSES)) { + const prefix = BECH32M_PREFIXES[network]; + const words = [P2A_WITNESS_VERSION, ...bech32m.toWords(P2A_WITNESS_PROGRAM)]; + const encoded = bech32m.encode(prefix, words); + if (encoded !== expected) { + throw new Error(`P2A address mismatch for ${network}: got ${encoded}, expected ${expected}`); + } + } +} + +verifyP2AAddresses(); + +export function getP2AAddress(): string { + const network = config.bitcoin.network || "mainnet"; + return P2A_ADDRESSES[network]; +} + +export function isP2AOutput(scriptPubKeyHex: string): boolean { + return scriptPubKeyHex === P2A_SCRIPT; +} + +export function calculateBumpReserve( + userRate: number, + fastestRate: number, + parentVsize: number, +): number { + if (userRate >= fastestRate) return 0; + return Math.ceil((fastestRate - userRate) * parentVsize + fastestRate * CHILD_VSIZE); +} |
