Skip to content

Commit b3f30de

Browse files
feat(abstract-utxo): add BIP322 message serialization format
Add support for serializing and deserializing BIP322 message signing transactions. Create types for message info and message broadcastable objects. Co-authored-by: llm-git <[email protected]> TICKET: BTC-2415
1 parent e52e59f commit b3f30de

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { decodeOrElse } from '@bitgo/sdk-core';
2+
import * as t from 'io-ts';
3+
4+
const BIP322MessageInfo = t.type({
5+
address: t.string,
6+
message: t.string,
7+
pubkeys: t.array(t.string),
8+
scriptType: t.union([
9+
t.literal('p2sh'),
10+
t.literal('p2shP2wsh'),
11+
t.literal('p2wsh'),
12+
t.literal('p2tr'),
13+
t.literal('p2trMusig2'),
14+
]),
15+
});
16+
17+
export type BIP322MessageInfo = t.TypeOf<typeof BIP322MessageInfo>;
18+
19+
const BIP322MessageBroadcastable = t.type({
20+
txHex: t.string,
21+
messageInfo: t.array(BIP322MessageInfo),
22+
});
23+
24+
export type BIP322MessageBroadcastable = t.TypeOf<typeof BIP322MessageBroadcastable>;
25+
26+
export function serializeBIP322BroadcastableMessage(message: BIP322MessageBroadcastable): string {
27+
return Buffer.from(JSON.stringify(message), 'utf8').toString('hex');
28+
}
29+
30+
export function deserializeBIP322BroadcastableMessage(hex: string): BIP322MessageBroadcastable {
31+
const json = JSON.parse(Buffer.from(hex, 'hex').toString('utf8'));
32+
return decodeOrElse(BIP322MessageBroadcastable.name, BIP322MessageBroadcastable, json, (error) => {
33+
throw new Error(`Failed to decode ${BIP322MessageBroadcastable.name}: ${error}`);
34+
});
35+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import assert from 'assert';
2+
3+
import {
4+
BIP322MessageBroadcastable,
5+
deserializeBIP322BroadcastableMessage,
6+
serializeBIP322BroadcastableMessage,
7+
} from '../src/transaction/bip322';
8+
9+
describe('BIP322', function () {
10+
describe('BIP322MessageBroadcastable', () => {
11+
it('should serialize and deserialize correctly', () => {
12+
const message: BIP322MessageBroadcastable = {
13+
txHex: '010203',
14+
messageInfo: [
15+
{
16+
address: 'someAddress',
17+
message: 'someMessage',
18+
pubkeys: ['pubkey1', 'pubkey2'],
19+
scriptType: 'p2sh',
20+
},
21+
],
22+
};
23+
24+
const serialized = serializeBIP322BroadcastableMessage(message);
25+
const deserialized = deserializeBIP322BroadcastableMessage(serialized);
26+
assert.deepStrictEqual(deserialized, message);
27+
});
28+
29+
it('should fail if there is an unsupported script type', function () {
30+
const message = {
31+
txHex: '010203',
32+
messageInfo: [
33+
{
34+
address: 'someAddress',
35+
message: 'someMessage',
36+
pubkeys: ['pubkey1', 'pubkey2'],
37+
scriptType: 'unsupported',
38+
},
39+
],
40+
} as unknown as BIP322MessageBroadcastable;
41+
42+
const serialized = serializeBIP322BroadcastableMessage(message);
43+
assert.throws(() => {
44+
deserializeBIP322BroadcastableMessage(serialized);
45+
});
46+
});
47+
});
48+
});

0 commit comments

Comments
 (0)