Skip to content

Commit 8baa60a

Browse files
Merge pull request #5717 from BitGo/BTC-1826.use-vendored-module
feat(utxo-staking): add babylon delegation message support
2 parents 882767c + 889b1c7 commit 8baa60a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+324
-3310
lines changed

modules/babylonlabs-io-btc-staking-ts/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"esbuild": "^0.20.2"
3737
},
3838
"dependencies": {
39-
"@babylonlabs-io/babylon-proto-ts": "0.0.3-canary.5",
39+
"@babylonlabs-io/babylon-proto-ts": "1.0.0",
4040
"@bitcoin-js/tiny-secp256k1-asmjs": "2.2.3",
4141
"@cosmjs/encoding": "^0.33.0",
4242
"bitcoinjs-lib": "^6.1.7",

modules/utxo-staking/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
"@bitgo/wasm-miniscript": "2.0.0-beta.7"
4646
},
4747
"devDependencies": {
48-
"bip174": "=2.1.1",
48+
"@bitgo/babylonlabs-io-btc-staking-ts": "^0.4.0-bitgo.1",
49+
"@babylonlabs-io/babylon-proto-ts": "1.0.0",
4950
"bitcoinjs-lib": "^6.1.7"
5051
}
5152
}

modules/utxo-staking/src/babylon/descriptor.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* https://github.com/babylonlabs-io/babylon/tree/main/docs
3+
* https://github.com/babylonlabs-io/babylon/blob/main/docs/staking-script.md
4+
*/
5+
16
import { Descriptor, ast } from '@bitgo/wasm-miniscript';
27

38
export function getUnspendableKey(): string {

modules/utxo-staking/src/babylon/testnet.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { BabylonDescriptorBuilder } from './descriptor';
44

55
// Source: https://github.com/babylonlabs-io/babylon/blob/v1.99.0-snapshot.250211/app/upgrades/v1/testnet/btcstaking_params.go#L149-L159
66
export const testnetStakingParams = {
7+
version: 5 /* it's the sixth element in the array */,
78
covenant_pks: [
89
'fa9d882d45f4060bdb8042183828cd87544f1ea997380e586cab77d5fd698737',
910
'0aee0509b16db71c999238a4827db945526859b13c95487ab46725357c9a9f25',
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"msg": {
3+
"stakerAddr": "bbn1qw3jhxaqax8rcq",
4+
"pop": {
5+
"btcSigType": 2,
6+
"btcSig": "77d73c7deef77de75f6dc79cddaf7c7f8f3aedbddcd36f787f6d35d37dfaf5d7dbdb46b9efb71e71de79f3cf74e7a6b7e9ff7475ae3c6da7dc7b9e7ae9cf74e1deb46dc6dcd5bd377b6df6e3be7475feddf3d71bd7c7757fa7dc6ddd3adf4ddb"
7+
},
8+
"btcPk": "7b6a08504c46336f985a5787a5423eb18c10b149fef29cd3316ad86f565cd2b9",
9+
"fpBtcPkList": [
10+
"d23c2c25e1fcf8fd1c21b9a402c19e2e309e531e45e92fb1e9805b6056b0cc76"
11+
],
12+
"stakingTime": 10000,
13+
"stakingValue": 55555,
14+
"stakingTx": "020000000111111111111111111111111111111111111111111111111111111111111111110000000000ffffffff0203d9000000000000225120f1871fc2ac3050b53dc35d502a9d94388f6f373b86f3905667945a8430cbd639bf51090000000000160014896f1ba65deaeb045bb3121e20e5744e66ca0e4800000000",
15+
"slashingTx": "020000000164da14050ffd0e6186c68a59f371a0adc95cc84b0502fe0915be7eba3f771bb30000000000ffffffff02d90a0000000000001600145be12624d08a2b424095d7c07221c33450d14bf1a2ba000000000000225120d5238530e223ef1bd34a8a98ee1708f6a8a87e7a2589d88de6700b9973ffff4600000000",
16+
"delegatorSlashingSig": "f10a5e6d722b459e87d713bf9af1113fa5eb7a1e41ff5738de7049fcf113beaa5f01228aecf27eb94045a9900b092091a63dbf546fd7d6c05d32d32cf8ad591d",
17+
"unbondingTime": 1008,
18+
"unbondingTx": "020000000164da14050ffd0e6186c68a59f371a0adc95cc84b0502fe0915be7eba3f771bb30000000000ffffffff0133d10000000000002251204dcea0c802236110602d7b1cc2e76ef5f1f05170b058685b4caf4367ac849d6b00000000",
19+
"unbondingValue": 53555,
20+
"unbondingSlashingTx": "0200000001c047c5904542017cfee57fdb350d6bf776a5ef8c46bc033f454a64b496d0ab9d0000000000ffffffff02750a0000000000001600145be12624d08a2b424095d7c07221c33450d14bf136b3000000000000225120d5238530e223ef1bd34a8a98ee1708f6a8a87e7a2589d88de6700b9973ffff4600000000",
21+
"delegatorUnbondingSlashingSig": "5bf9bed637fbd109d53c60df4093b166ba06a27b90c6b7d05beb9124a19fc62d1d17522a309d4dd7d8dc2eed954dcb3f628f44ae9837c02b91545fa313de6e17"
22+
},
23+
"msgBytes": "0a1262626e317177336a6878617161783872637112640802126077d73c7deef77de75f6dc79cddaf7c7f8f3aedbddcd36f787f6d35d37dfaf5d7dbdb46b9efb71e71de79f3cf74e7a6b7e9ff7475ae3c6da7dc7b9e7ae9cf74e1deb46dc6dcd5bd377b6df6e3be7475feddf3d71bd7c7757fa7dc6ddd3adf4ddb1a207b6a08504c46336f985a5787a5423eb18c10b149fef29cd3316ad86f565cd2b92220d23c2c25e1fcf8fd1c21b9a402c19e2e309e531e45e92fb1e9805b6056b0cc7628904e3083b2033a7d020000000111111111111111111111111111111111111111111111111111111111111111110000000000ffffffff0203d9000000000000225120f1871fc2ac3050b53dc35d502a9d94388f6f373b86f3905667945a8430cbd639bf51090000000000160014896f1ba65deaeb045bb3121e20e5744e66ca0e48000000004a7d020000000164da14050ffd0e6186c68a59f371a0adc95cc84b0502fe0915be7eba3f771bb30000000000ffffffff02d90a0000000000001600145be12624d08a2b424095d7c07221c33450d14bf1a2ba000000000000225120d5238530e223ef1bd34a8a98ee1708f6a8a87e7a2589d88de6700b9973ffff46000000005240f10a5e6d722b459e87d713bf9af1113fa5eb7a1e41ff5738de7049fcf113beaa5f01228aecf27eb94045a9900b092091a63dbf546fd7d6c05d32d32cf8ad591d58f007625e020000000164da14050ffd0e6186c68a59f371a0adc95cc84b0502fe0915be7eba3f771bb30000000000ffffffff0133d10000000000002251204dcea0c802236110602d7b1cc2e76ef5f1f05170b058685b4caf4367ac849d6b0000000068b3a203727d0200000001c047c5904542017cfee57fdb350d6bf776a5ef8c46bc033f454a64b496d0ab9d0000000000ffffffff02750a0000000000001600145be12624d08a2b424095d7c07221c33450d14bf136b3000000000000225120d5238530e223ef1bd34a8a98ee1708f6a8a87e7a2589d88de6700b9973ffff46000000007a405bf9bed637fbd109d53c60df4093b166ba06a27b90c6b7d05beb9124a19fc62d1d17522a309d4dd7d8dc2eed954dcb3f628f44ae9837c02b91545fa313de6e17",
24+
"stakingTx": {
25+
"version": 2,
26+
"locktime": 0,
27+
"ins": [
28+
{
29+
"hash": "1111111111111111111111111111111111111111111111111111111111111111",
30+
"index": 0,
31+
"script": "",
32+
"sequence": 4294967295,
33+
"witness": []
34+
}
35+
],
36+
"outs": [
37+
{
38+
"script": "5120f1871fc2ac3050b53dc35d502a9d94388f6f373b86f3905667945a8430cbd639",
39+
"value": 55555
40+
},
41+
{
42+
"script": "0014896f1ba65deaeb045bb3121e20e5744e66ca0e48",
43+
"value": 610751
44+
}
45+
]
46+
}
47+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"msg": {
3+
"stakerAddr": "bbn1qw3jhxaqax8rcq",
4+
"pop": {
5+
"btcSigType": 2,
6+
"btcSig": "77d73c7deef77de75f6dc79cddaf7c7f8f3aedbddcd36f787f6d35d37dfaf5d7dbdb46b9efb71e71de79f3cf74e7a6b7e9ff7475ae3c6da7dc7b9e7ae9cf74e1deb46dc6dcd5bd377b6df6e3be7475feddf3d71bd7c7757fa7dc6ddd3adf4ddb"
7+
},
8+
"btcPk": "7b6a08504c46336f985a5787a5423eb18c10b149fef29cd3316ad86f565cd2b9",
9+
"fpBtcPkList": [
10+
"850854d26df93570748d94e3da361f134c522f7970bd7f8701a164547308a900"
11+
],
12+
"stakingTime": 10000,
13+
"stakingValue": 55555,
14+
"stakingTx": "020000000111111111111111111111111111111111111111111111111111111111111111110000000000ffffffff0203d9000000000000225120788d73d75d7dd88d3612f7a91d5b3d6ad4778d8b49176f9539d322980b2f4fd7bf51090000000000160014896f1ba65deaeb045bb3121e20e5744e66ca0e4800000000",
15+
"slashingTx": "0200000001a999d7bc6af1a17cd4e70d0fd875a1734152dfb55f9166240f35965c79fa36c20000000000ffffffff02d90a0000000000001600145be12624d08a2b424095d7c07221c33450d14bf1a2ba000000000000225120d5238530e223ef1bd34a8a98ee1708f6a8a87e7a2589d88de6700b9973ffff4600000000",
16+
"delegatorSlashingSig": "c032a98f7d16adc8a1438310782b35aa0e5d23abca1deb1d743461e7649e0cca07b030c2f083ffb21b88b8de1198a919853b576a7e9c4b80f5bcd6cb544536b4",
17+
"unbondingTime": 1008,
18+
"unbondingTx": "0200000001a999d7bc6af1a17cd4e70d0fd875a1734152dfb55f9166240f35965c79fa36c20000000000ffffffff0133d1000000000000225120dec7bc887b110e2c10f1c9a2212cd961e95184870c91d88c9a3727f4ef4c303c00000000",
19+
"unbondingValue": 53555,
20+
"unbondingSlashingTx": "02000000014c2a294c5e31886937d0985e69e65314419e8866e5ab859cb2903cbe420a555a0000000000ffffffff02750a0000000000001600145be12624d08a2b424095d7c07221c33450d14bf136b3000000000000225120d5238530e223ef1bd34a8a98ee1708f6a8a87e7a2589d88de6700b9973ffff4600000000",
21+
"delegatorUnbondingSlashingSig": "71fdbb1e85db78b2406f7f6a8bbbeecd9be27d6099c4b80b2cf09403a855b55d057805576afad3bf92b79487e9559ad355c9728f95fe191c7a78b21284925fd0"
22+
},
23+
"msgBytes": "0a1262626e317177336a6878617161783872637112640802126077d73c7deef77de75f6dc79cddaf7c7f8f3aedbddcd36f787f6d35d37dfaf5d7dbdb46b9efb71e71de79f3cf74e7a6b7e9ff7475ae3c6da7dc7b9e7ae9cf74e1deb46dc6dcd5bd377b6df6e3be7475feddf3d71bd7c7757fa7dc6ddd3adf4ddb1a207b6a08504c46336f985a5787a5423eb18c10b149fef29cd3316ad86f565cd2b92220850854d26df93570748d94e3da361f134c522f7970bd7f8701a164547308a90028904e3083b2033a7d020000000111111111111111111111111111111111111111111111111111111111111111110000000000ffffffff0203d9000000000000225120788d73d75d7dd88d3612f7a91d5b3d6ad4778d8b49176f9539d322980b2f4fd7bf51090000000000160014896f1ba65deaeb045bb3121e20e5744e66ca0e48000000004a7d0200000001a999d7bc6af1a17cd4e70d0fd875a1734152dfb55f9166240f35965c79fa36c20000000000ffffffff02d90a0000000000001600145be12624d08a2b424095d7c07221c33450d14bf1a2ba000000000000225120d5238530e223ef1bd34a8a98ee1708f6a8a87e7a2589d88de6700b9973ffff46000000005240c032a98f7d16adc8a1438310782b35aa0e5d23abca1deb1d743461e7649e0cca07b030c2f083ffb21b88b8de1198a919853b576a7e9c4b80f5bcd6cb544536b458f007625e0200000001a999d7bc6af1a17cd4e70d0fd875a1734152dfb55f9166240f35965c79fa36c20000000000ffffffff0133d1000000000000225120dec7bc887b110e2c10f1c9a2212cd961e95184870c91d88c9a3727f4ef4c303c0000000068b3a203727d02000000014c2a294c5e31886937d0985e69e65314419e8866e5ab859cb2903cbe420a555a0000000000ffffffff02750a0000000000001600145be12624d08a2b424095d7c07221c33450d14bf136b3000000000000225120d5238530e223ef1bd34a8a98ee1708f6a8a87e7a2589d88de6700b9973ffff46000000007a4071fdbb1e85db78b2406f7f6a8bbbeecd9be27d6099c4b80b2cf09403a855b55d057805576afad3bf92b79487e9559ad355c9728f95fe191c7a78b21284925fd0",
24+
"stakingTx": {
25+
"version": 2,
26+
"locktime": 0,
27+
"ins": [
28+
{
29+
"hash": "1111111111111111111111111111111111111111111111111111111111111111",
30+
"index": 0,
31+
"script": "",
32+
"sequence": 4294967295,
33+
"witness": []
34+
}
35+
],
36+
"outs": [
37+
{
38+
"script": "5120788d73d75d7dd88d3612f7a91d5b3d6ad4778d8b49176f9539d322980b2f4fd7",
39+
"value": 55555
40+
},
41+
{
42+
"script": "0014896f1ba65deaeb045bb3121e20e5744e66ca0e48",
43+
"value": 610751
44+
}
45+
]
46+
}
47+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import assert from 'assert';
2+
3+
import * as utxolib from '@bitgo/utxo-lib';
4+
import { ECPairInterface } from '@bitgo/utxo-lib';
5+
import { getKey } from '@bitgo/utxo-core/testutil';
6+
7+
export function getECKey(seed: string): ECPairInterface {
8+
const { privateKey } = getKey(seed);
9+
assert(privateKey);
10+
return utxolib.ECPair.fromPrivateKey(privateKey);
11+
}
12+
13+
export function getECKeys(key: string, count: number): ECPairInterface[] {
14+
return Array.from({ length: count }, (_, i) => getECKey(`${key}${i}`));
15+
}
16+
17+
export function getXOnlyPubkey(key: ECPairInterface): Buffer {
18+
return key.publicKey.subarray(1);
19+
}
20+
21+
export function fromXOnlyPublicKey(key: Buffer): ECPairInterface {
22+
for (const prefix of [0x02, 0x03]) {
23+
try {
24+
return utxolib.ECPair.fromPublicKey(Buffer.concat([Buffer.from([prefix]), key]));
25+
} catch {
26+
continue;
27+
}
28+
}
29+
throw new Error('Invalid x-only public key');
30+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import assert from 'assert';
2+
3+
import * as bitcoinjslib from 'bitcoinjs-lib';
4+
import { Descriptor } from '@bitgo/wasm-miniscript';
5+
import { ECPairInterface } from '@bitgo/utxo-lib';
6+
import { toWrappedPsbt } from '@bitgo/utxo-core/descriptor';
7+
8+
export function getSignedPsbt(
9+
psbt: bitcoinjslib.Psbt,
10+
descriptor: Descriptor,
11+
signers: ECPairInterface[],
12+
{ finalize = false }
13+
): bitcoinjslib.Psbt {
14+
const wrappedPsbt = toWrappedPsbt(psbt.toBuffer());
15+
const signedInputs = psbt.data.inputs.flatMap((input, i) => {
16+
assert(input.witnessUtxo);
17+
if (Buffer.from(descriptor.scriptPubkey()).equals(input.witnessUtxo.script)) {
18+
wrappedPsbt.updateInputWithDescriptor(i, descriptor);
19+
const signResults = signers.map((signer) => {
20+
assert(signer.privateKey);
21+
return wrappedPsbt.signWithPrv(signer.privateKey);
22+
});
23+
return [[i, signResults]];
24+
}
25+
return [];
26+
});
27+
assert(signedInputs.length > 0);
28+
if (finalize) {
29+
wrappedPsbt.finalize();
30+
}
31+
return bitcoinjslib.Psbt.fromBuffer(Buffer.from(wrappedPsbt.serialize()));
32+
}
33+
34+
export function getSignedExtract(
35+
psbt: bitcoinjslib.Psbt,
36+
descriptor: Descriptor,
37+
signers: ECPairInterface[]
38+
): bitcoinjslib.Transaction {
39+
return getSignedPsbt(psbt, descriptor, signers, { finalize: true }).extractTransaction();
40+
}

0 commit comments

Comments
 (0)