Skip to content

Commit 858fe76

Browse files
committed
prove every code assumption with real transaction data
- Classic send (ID 0, 4-byte encoding) via OP_RETURN: block 489,000 tx 6335eefb... (pre-short_tx_type_id, sends TRIGGERS) - OLGA already proves 4-byte encoding via multisig (ID 30, block ~310K) - Rune early exit (byte > 0x4e): tx 1af2a846... correctly rejected - Short OP_RETURN early exit (< 22 hex): tx 28baf937... correctly rejected - P2TR "ord" inscription envelope: constructed from official Counterparty composer unit test (composertaproot_test.py) -- FAKE, clearly marked. Zero mainnet/testnet txs exist (inscription param defaults to false, confirmed by Counterparty team in GitHub issue #3179). 19 Counterparty tests covering all 3 encodings, both type ID formats, and early exit paths.
1 parent c9d26c2 commit 858fe76

3 files changed

Lines changed: 122 additions & 0 deletions

src/counterparty/counterparty-parser.service.spec.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,5 +215,88 @@ describe('CounterpartyParserService', () => {
215215
// CBOR-encoded fairminter payload (97 bytes, first byte was the type ID)
216216
expect(result.getMessageData().length).toBe(97);
217217
});
218+
219+
// !! FAKE TRANSACTION -- NOT FROM MAINNET OR ANY TESTNET !!
220+
//
221+
// The "ord" inscription envelope (OP_FALSE OP_IF "ord" [7] "xcp" ... OP_ENDIF)
222+
// is used when composing with inscription=true (opt-in, defaults to false).
223+
// As of March 2026, zero transactions on mainnet, testnet3, or testnet4 use
224+
// this format. The Counterparty team confirmed inscription defaults to false
225+
// (GitHub issue #3179). No public testnet API is available to search.
226+
//
227+
// The envelope script below is constructed from the official Counterparty
228+
// composer unit test: counterparty-core/test/units/api/composertaproot_test.py
229+
// The CBOR metadata and content bytes are taken verbatim from that test.
230+
//
231+
// TODO: Replace with a real mainnet/testnet transaction when one exists.
232+
it('should parse an ord inscription envelope (FAKE -- from Counterparty regtest test data)', () => {
233+
const txn = readTransaction('counterparty_regtest_ord_envelope_fairminter');
234+
const result = CounterpartyParserService.parse(txn)!;
235+
236+
expect(result.type).toBe(DigitalArtifactType.Counterparty);
237+
expect(result.encoding).toBe('p2tr');
238+
expect(result.messageTypeId).toBe(90);
239+
expect(result.messageType).toBe('fairminter');
240+
241+
// The re-encoded CBOR contains: fairminter fields + "text/plain" + content bytes
242+
expect(result.getMessageData().length).toBe(77);
243+
});
244+
});
245+
246+
// ===========================================================================
247+
// 4-byte message type ID (pre-short_tx_type_id, before block 489,956)
248+
// ===========================================================================
249+
250+
describe('parse — 4-byte message type ID', () => {
251+
// Classic send (ID 0) via OP_RETURN -- uses 4-byte big-endian encoding (00 00 00 00)
252+
// Block 489,000 (before short_tx_type_id activation at 489,956)
253+
// Sends 2,100,000,000 TRIGGERS
254+
const CLASSIC_SEND_TXID = '6335eefb68f5e57eddb95b329c368615e53cf5efe346be14d271c88a63b5461e';
255+
256+
it('should parse a classic send (ID 0, 4-byte encoding) via OP_RETURN', () => {
257+
const txn = readTransaction(CLASSIC_SEND_TXID);
258+
const result = CounterpartyParserService.parse(txn)!;
259+
260+
expect(result.encoding).toBe('opreturn');
261+
expect(result.messageTypeId).toBe(0);
262+
expect(result.messageType).toBe('send');
263+
264+
// Classic send payload: asset_id (8 bytes BE) + quantity (8 bytes BE) = 16 bytes
265+
// API raw data: 20 bytes = 4 bytes type ID (00000000) + 16 bytes payload
266+
expect(result.getMessageData().length).toBe(16);
267+
});
268+
269+
it('should parse a broadcast (ID 30, 4-byte encoding) via multisig (OLGA)', () => {
270+
// OLGA predates short_tx_type_id -- uses 4-byte encoding even for ID 30
271+
// API raw data: 9136 bytes = 4 bytes type ID (0000001e) + 9132 bytes payload
272+
const txn = readTransaction(OLGA_MULTISIG_TXID);
273+
const result = CounterpartyParserService.parse(txn)!;
274+
275+
expect(result.messageTypeId).toBe(30);
276+
expect(result.getMessageData().length).toBe(9132);
277+
});
278+
});
279+
280+
// ===========================================================================
281+
// Early exit correctness — reject non-Counterparty OP_RETURN transactions
282+
// ===========================================================================
283+
284+
describe('early exits', () => {
285+
// Rune OP_RETURN starts with 6a5d (OP_RETURN + OP_PUSHNUM_13)
286+
// Our code rejects byte[1] > 0x4e before ARC4 decryption
287+
const RUNE_TXID = '1af2a846befbfac4091bf540adad4fd1a86604c26c004066077d5fe22510e99b';
288+
289+
// Short OP_RETURN (8 hex chars = 4 bytes, below our 22 hex char minimum)
290+
const SHORT_OP_RETURN_TXID = '28baf9374797230174803b0c3f63fd39e22bb1972a25cc2af4e791ca8fc89dae';
291+
292+
it('should reject a Rune transaction (OP_PUSHNUM_13 early exit)', () => {
293+
const txn = readTransaction(RUNE_TXID);
294+
expect(CounterpartyParserService.parse(txn)).toBeNull();
295+
});
296+
297+
it('should reject a short OP_RETURN transaction (< 22 hex chars)', () => {
298+
const txn = readTransaction(SHORT_OP_RETURN_TXID);
299+
expect(CounterpartyParserService.parse(txn)).toBeNull();
300+
});
218301
});
219302
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"txid":"6335eefb68f5e57eddb95b329c368615e53cf5efe346be14d271c88a63b5461e","version":1,"locktime":0,"vin":[{"txid":"fc6b1ffbfa0a9a48268a509c2664f26148d0cc965929836235491975d9312a7e","vout":2,"prevout":{"scriptpubkey":"76a9145884d72365ca5280b817de42476a9a56528ad7c088ac","scriptpubkey_asm":"OP_DUP OP_HASH160 OP_PUSHBYTES_20 5884d72365ca5280b817de42476a9a56528ad7c0 OP_EQUALVERIFY OP_CHECKSIG","scriptpubkey_type":"p2pkh","scriptpubkey_address":"1953bnyqwmLmrVfbx6n6TjkBomkwkp8Lie","value":1762976},"scriptsig":"4830450221008de8c538522bdb3b2a06ad7b3d90c71b616d3596ded07a1650f6bcb6362e79f9022018cbe23d5abe2a0546bb6be6014c363fc736b135eeb48823dda0aed92e06d3d8012103d6cecd548977c160a059e64895b423f8e73cfca3ec9eee96c3e3e9369aa337c7","scriptsig_asm":"OP_PUSHBYTES_72 30450221008de8c538522bdb3b2a06ad7b3d90c71b616d3596ded07a1650f6bcb6362e79f9022018cbe23d5abe2a0546bb6be6014c363fc736b135eeb48823dda0aed92e06d3d801 OP_PUSHBYTES_33 03d6cecd548977c160a059e64895b423f8e73cfca3ec9eee96c3e3e9369aa337c7","is_coinbase":false,"sequence":4294967295}],"vout":[{"scriptpubkey":"76a91451acdda2dc2ce3e96e48fa4ae0315e58042c462f88ac","scriptpubkey_asm":"OP_DUP OP_HASH160 OP_PUSHBYTES_20 51acdda2dc2ce3e96e48fa4ae0315e58042c462f OP_EQUALVERIFY OP_CHECKSIG","scriptpubkey_type":"p2pkh","scriptpubkey_address":"18SrpTp5otmJB8cprbsJb2HbmC6P3A7C7R","value":5430},{"scriptpubkey":"6a1c399752ffafe57a98080a8608ac82464e36b85ce5c7ccaaf04806760d","scriptpubkey_asm":"OP_RETURN OP_PUSHBYTES_28 399752ffafe57a98080a8608ac82464e36b85ce5c7ccaaf04806760d","scriptpubkey_type":"op_return","value":0},{"scriptpubkey":"76a9145884d72365ca5280b817de42476a9a56528ad7c088ac","scriptpubkey_asm":"OP_DUP OP_HASH160 OP_PUSHBYTES_20 5884d72365ca5280b817de42476a9a56528ad7c0 OP_EQUALVERIFY OP_CHECKSIG","scriptpubkey_type":"p2pkh","scriptpubkey_address":"1953bnyqwmLmrVfbx6n6TjkBomkwkp8Lie","value":1714373}],"size":265,"weight":1060,"sigops":8,"fee":43173,"status":{"confirmed":true,"block_height":489000,"block_hash":"000000000000000000cd2640a061b810e668e029d63b37645a59e8caf8fc11f4","block_time":1507530156}}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"txid": "counterparty_regtest_ord_envelope_fairminter",
3+
"version": 2,
4+
"locktime": 0,
5+
"vin": [
6+
{
7+
"txid": "52e8a861037edf4af1316878865e256d83680c65fcc72efc78a6ffe1d972fbd9",
8+
"vout": 0,
9+
"prevout": {
10+
"scriptpubkey": "512079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
11+
"scriptpubkey_type": "v1_p2tr",
12+
"value": 100000
13+
},
14+
"scriptsig": "",
15+
"witness": [
16+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
17+
"0063036f726401070378637001010a746578742f706c61696e01053092185a1b000018c0fdcdeb5f0000010a001903e818641a000c35001a000dbba018321a000cf8501a00989680f4f4f5f50013756e6520617373657420737570657220746f70682079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac",
18+
"c179be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
19+
],
20+
"sequence": 4294967295
21+
}
22+
],
23+
"vout": [
24+
{
25+
"scriptpubkey": "6a08434e545250525459",
26+
"scriptpubkey_type": "op_return",
27+
"value": 0
28+
}
29+
],
30+
"size": 300,
31+
"weight": 600,
32+
"fee": 330,
33+
"status": {
34+
"confirmed": true,
35+
"block_height": 999999,
36+
"block_hash": "0000000000000000000000000000000000000000000000000000000000000000"
37+
}
38+
}

0 commit comments

Comments
 (0)