@@ -8,11 +8,13 @@ import * as babylonProtobuf from '@babylonlabs-io/babylon-proto-ts';
88import * as bitcoinjslib from 'bitcoinjs-lib' ;
99import * as utxolib from '@bitgo/utxo-lib' ;
1010import { Descriptor } from '@bitgo/wasm-miniscript' ;
11+ import { toXOnlyPublicKey } from '@bitgo/utxo-core' ;
1112import { toWrappedPsbt } from '@bitgo/utxo-core/descriptor' ;
1213
1314import { BabylonDescriptorBuilder } from './descriptor' ;
1415import { createStakingManager } from './stakingManager' ;
1516import { getStakingParams } from './stakingParams' ;
17+ import { BabylonNetworkLike , toBitcoinJsNetwork } from './network' ;
1618
1719export type ValueWithTypeUrl < T > = { typeUrl : string ; value : T } ;
1820
@@ -86,6 +88,77 @@ type Result = {
8688 stakingTx : bitcoinjslib . Transaction ;
8789} ;
8890
91+ /**
92+ * @param stakingKey - this is the single-sig key that is used for co-signing the staking output
93+ * @param changeAddress - this is unrelated to the staking key and is used for the change output
94+ */
95+ export function toStakerInfo (
96+ stakingKey : utxolib . ECPairInterface | Buffer | string ,
97+ changeAddress : string
98+ ) : vendor . StakerInfo {
99+ if ( typeof stakingKey === 'object' && 'publicKey' in stakingKey ) {
100+ stakingKey = stakingKey . publicKey ;
101+ }
102+ if ( typeof stakingKey === 'string' ) {
103+ stakingKey = Buffer . from ( stakingKey , 'hex' ) ;
104+ }
105+ return {
106+ publicKeyNoCoordHex : toXOnlyPublicKey ( stakingKey ) . toString ( 'hex' ) ,
107+ address : changeAddress ,
108+ } ;
109+ }
110+
111+ export function createStaking (
112+ network : BabylonNetworkLike ,
113+ blockHeight : number ,
114+ stakerBtcInfo : vendor . StakerInfo ,
115+ stakingInput : vendor . StakingInputs ,
116+ versionedParams : vendor . VersionedStakingParams [ ] = getStakingParams ( network )
117+ ) : vendor . Staking {
118+ if ( blockHeight === 0 ) {
119+ throw new Error ( 'Babylon BTC tip height cannot be 0' ) ;
120+ }
121+
122+ // Get the Babylon params based on the BTC tip height from Babylon chain
123+ const params = vendor . getBabylonParamByBtcHeight ( blockHeight , versionedParams ) ;
124+
125+ return new vendor . Staking (
126+ toBitcoinJsNetwork ( network ) ,
127+ stakerBtcInfo ,
128+ params ,
129+ stakingInput . finalityProviderPkNoCoordHex ,
130+ stakingInput . stakingTimelock
131+ ) ;
132+ }
133+
134+ type TransactionLike =
135+ | bitcoinjslib . Psbt
136+ | bitcoinjslib . Transaction
137+ | utxolib . Transaction
138+ | utxolib . bitgo . UtxoTransaction < bigint | number >
139+ | utxolib . Psbt
140+ | utxolib . bitgo . UtxoPsbt ;
141+
142+ function toStakingTransactionFromPsbt (
143+ psbt : bitcoinjslib . Psbt | utxolib . Psbt | utxolib . bitgo . UtxoPsbt
144+ ) : bitcoinjslib . Transaction {
145+ if ( ! ( psbt instanceof utxolib . bitgo . UtxoPsbt ) ) {
146+ psbt = utxolib . bitgo . createPsbtFromBuffer ( psbt . toBuffer ( ) , utxolib . networks . bitcoin ) ;
147+ }
148+ if ( psbt instanceof utxolib . bitgo . UtxoPsbt ) {
149+ // only utxolib.bitgo.UtxoPsbt has the getUnsignedTx method
150+ return bitcoinjslib . Transaction . fromHex ( psbt . getUnsignedTx ( ) . toHex ( ) ) ;
151+ }
152+ throw new Error ( 'illegal state' ) ;
153+ }
154+
155+ export function toStakingTransaction ( tx : TransactionLike ) : bitcoinjslib . Transaction {
156+ if ( tx instanceof bitcoinjslib . Psbt || tx instanceof utxolib . Psbt ) {
157+ return toStakingTransactionFromPsbt ( tx ) ;
158+ }
159+ return bitcoinjslib . Transaction . fromHex ( tx . toHex ( ) ) ;
160+ }
161+
89162/*
90163 * This is mostly lifted from
91164 * https://github.com/babylonlabs-io/btc-staking-ts/blob/v0.4.0-rc.2/src/staking/manager.ts#L100-L172
0 commit comments