@bitgo-beta/babylonlabs-io-btc-staking-ts 0.4.0-beta.515 → 0.4.0-beta.517

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -202,6 +202,49 @@ export declare class Staking {
202
202
  * @throws {StakingError} - If the transaction cannot be built
203
203
  */
204
204
  createStakingTransaction(stakingAmountSat: number, inputUTXOs: UTXO[], feeRate: number): TransactionResult;
205
+ /**
206
+ * Creates a staking expansion transaction that extends an existing BTC stake
207
+ * to new finality providers or renews the timelock.
208
+ *
209
+ * This method implements RFC 037 BTC Stake Expansion,
210
+ * allowing existing active BTC staking transactions
211
+ * to extend their delegation to new finality providers without going through
212
+ * the full unbonding process.
213
+ *
214
+ * The expansion transaction:
215
+ * 1. Spends the previous staking transaction output as the first input
216
+ * 2. Uses funding UTXO as additional input to cover transaction fees or
217
+ * to increase the staking amount
218
+ * 3. Creates a new staking output with expanded finality provider coverage or
219
+ * renews the timelock
220
+ * 4. Has an output returning the remaining funds as change (if any) to the
221
+ * staker BTC address
222
+ *
223
+ * @param {number} stakingAmountSat - The total staking amount in satoshis
224
+ * (The amount had to be equal to the previous staking amount for now, this
225
+ * lib does not yet support increasing the staking amount at this stage)
226
+ * @param {UTXO[]} inputUTXOs - Available UTXOs to use for funding the
227
+ * expansion transaction fees. Only one will be selected for the expansion
228
+ * @param {number} feeRate - Fee rate in satoshis per byte for the
229
+ * expansion transaction
230
+ * @param {StakingParams} paramsForPreviousStakingTx - Staking parameters
231
+ * used in the previous staking transaction
232
+ * @param {Object} previousStakingTxInfo - Necessary information to spend the
233
+ * previous staking transaction.
234
+ * @returns {TransactionResult & { fundingUTXO: UTXO }} - An object containing
235
+ * the unsigned expansion transaction and calculated fee, and the funding UTXO
236
+ * @throws {StakingError} - If the transaction cannot be built or validation
237
+ * fails
238
+ */
239
+ createStakingExpansionTransaction(stakingAmountSat: number, inputUTXOs: UTXO[], feeRate: number, paramsForPreviousStakingTx: StakingParams, previousStakingTxInfo: {
240
+ stakingTx: Transaction;
241
+ stakingInput: {
242
+ finalityProviderPksNoCoordHex: string[];
243
+ stakingTimelock: number;
244
+ };
245
+ }): TransactionResult & {
246
+ fundingUTXO: UTXO;
247
+ };
205
248
  /**
206
249
  * Create a staking psbt based on the existing staking transaction.
207
250
  *
@@ -212,6 +255,28 @@ export declare class Staking {
212
255
  * @returns {Psbt} - The psbt.
213
256
  */
214
257
  toStakingPsbt(stakingTx: Transaction, inputUTXOs: UTXO[]): Psbt;
258
+ /**
259
+ * Convert a staking expansion transaction to a PSBT.
260
+ *
261
+ * @param {Transaction} stakingExpansionTx - The staking expansion
262
+ * transaction to convert
263
+ * @param {UTXO[]} inputUTXOs - Available UTXOs for the
264
+ * funding input (second input)
265
+ * @param {StakingParams} paramsForPreviousStakingTx - Staking parameters
266
+ * used for the previous staking transaction
267
+ * @param {Object} previousStakingTxInfo - Information about the previous
268
+ * staking transaction
269
+ * @returns {Psbt} The PSBT for the staking expansion transaction
270
+ * @throws {Error} If the previous staking output cannot be found or
271
+ * validation fails
272
+ */
273
+ toStakingExpansionPsbt(stakingExpansionTx: Transaction, inputUTXOs: UTXO[], paramsForPreviousStakingTx: StakingParams, previousStakingTxInfo: {
274
+ stakingTx: Transaction;
275
+ stakingInput: {
276
+ finalityProviderPksNoCoordHex: string[];
277
+ stakingTimelock: number;
278
+ };
279
+ }): Psbt;
215
280
  /**
216
281
  * Create an unbonding transaction for staking.
217
282
  *
@@ -291,6 +356,7 @@ export interface ManagerEvents {
291
356
  "delegation:stake": (data?: EventData) => void;
292
357
  "delegation:unbond": (data?: EventData) => void;
293
358
  "delegation:withdraw": (data?: EventData) => void;
359
+ "delegation:expand": (data?: EventData) => void;
294
360
  }
295
361
  export type DelegationEvent = keyof ManagerEvents;
296
362
  export interface Action {
@@ -322,6 +388,7 @@ export interface SignPsbtOptions {
322
388
  export interface BtcProvider {
323
389
  signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string>;
324
390
  signMessage: (message: string, type: "ecdsa" | "bip322-simple") => Promise<string>;
391
+ getTransactionHex(txid: string): Promise<string>;
325
392
  }
326
393
  export interface BabylonProvider {
327
394
  /**
@@ -338,6 +405,18 @@ export interface BabylonProvider {
338
405
  typeUrl: string;
339
406
  value: T;
340
407
  }) => Promise<Uint8Array>;
408
+ /**
409
+ * Gets the current height of the Babylon Genesis chain.
410
+ *
411
+ * @returns {Promise<number>} The current Babylon chain height
412
+ */
413
+ getCurrentHeight?: () => Promise<number>;
414
+ /**
415
+ * Gets the chain ID of the Babylon Genesis chain.
416
+ *
417
+ * @returns {Promise<string>} The Babylon chain ID
418
+ */
419
+ getChainId?: () => Promise<string>;
341
420
  }
342
421
  export interface StakingInputs {
343
422
  finalityProviderPksNoCoordHex: string[];
@@ -349,13 +428,40 @@ export interface InclusionProof {
349
428
  merkle: string[];
350
429
  blockHashHex: string;
351
430
  }
431
+ /**
432
+ * Upgrade configuration for Babylon POP (Proof of Possession) context.
433
+ * This is used to determine when to switch to the new POP context format
434
+ * based on the Babylon chain height and version.
435
+ */
436
+ export interface UpgradeConfig {
437
+ /**
438
+ * POP context upgrade configuration.
439
+ */
440
+ pop?: PopUpgradeConfig;
441
+ }
442
+ /**
443
+ * Configuration for POP context upgrade.
444
+ * - upgradeHeight: The Babylon chain height at which the POP context upgrade is activated.
445
+ * - version: The version of the POP context to use after the upgrade.
446
+ */
447
+ export interface PopUpgradeConfig {
448
+ /**
449
+ * The Babylon chain height at which the POP context upgrade is activated.
450
+ */
451
+ upgradeHeight: number;
452
+ /**
453
+ * The version of the POP context to use after the upgrade.
454
+ */
455
+ version: number;
456
+ }
352
457
  export declare class BabylonBtcStakingManager {
353
458
  protected network: networks.Network;
354
459
  protected stakingParams: VersionedStakingParams[];
355
460
  protected btcProvider: BtcProvider;
356
461
  protected babylonProvider: BabylonProvider;
357
462
  protected ee?: Emitter<ManagerEvents> | undefined;
358
- constructor(network: networks.Network, stakingParams: VersionedStakingParams[], btcProvider: BtcProvider, babylonProvider: BabylonProvider, ee?: Emitter<ManagerEvents> | undefined);
463
+ private upgradeConfig?;
464
+ constructor(network: networks.Network, stakingParams: VersionedStakingParams[], btcProvider: BtcProvider, babylonProvider: BabylonProvider, ee?: Emitter<ManagerEvents> | undefined, upgradeConfig?: UpgradeConfig);
359
465
  /**
360
466
  * Creates a signed Pre-Staking Registration transaction that is ready to be
361
467
  * sent to the Babylon chain.
@@ -376,6 +482,41 @@ export declare class BabylonBtcStakingManager {
376
482
  signedBabylonTx: Uint8Array;
377
483
  stakingTx: Transaction;
378
484
  }>;
485
+ /**
486
+ * Create a signed staking expansion transaction that is ready to be sent to
487
+ * the Babylon chain.
488
+ */
489
+ stakingExpansionRegistrationBabylonTransaction(stakerBtcInfo: StakerInfo, stakingInput: StakingInputs, babylonBtcTipHeight: number, inputUTXOs: UTXO[], feeRate: number, babylonAddress: string, previousStakingTxInfo: {
490
+ stakingTx: Transaction;
491
+ paramVersion: number;
492
+ stakingInput: StakingInputs;
493
+ }): Promise<{
494
+ signedBabylonTx: Uint8Array;
495
+ stakingTx: Transaction;
496
+ }>;
497
+ /**
498
+ * Estimates the transaction fee for a BTC staking expansion transaction.
499
+ *
500
+ * @param {StakerInfo} stakerBtcInfo - The staker's Bitcoin information
501
+ * including address and public key
502
+ * @param {number} babylonBtcTipHeight - The current Babylon BTC tip height
503
+ * used to determine staking parameters
504
+ * @param {StakingInputs} stakingInput - The new staking input parameters for
505
+ * the expansion
506
+ * @param {UTXO[]} inputUTXOs - Available UTXOs that can be used for funding
507
+ * the expansion transaction
508
+ * @param {number} feeRate - Fee rate in satoshis per byte for the expansion
509
+ * transaction
510
+ * @param {Object} previousStakingTxInfo - Information about the previous
511
+ * staking transaction being expanded
512
+ * @returns {number} - The estimated transaction fee in satoshis
513
+ * @throws {Error} - If validation fails or the fee cannot be calculated
514
+ */
515
+ estimateBtcStakingExpansionFee(stakerBtcInfo: StakerInfo, babylonBtcTipHeight: number, stakingInput: StakingInputs, inputUTXOs: UTXO[], feeRate: number, previousStakingTxInfo: {
516
+ stakingTx: Transaction;
517
+ paramVersion: number;
518
+ stakingInput: StakingInputs;
519
+ }): number;
379
520
  /**
380
521
  * Creates a signed post-staking registration transaction that is ready to be
381
522
  * sent to the Babylon chain. This is used when a staking transaction is
@@ -424,6 +565,35 @@ export declare class BabylonBtcStakingManager {
424
565
  * @returns The signed staking transaction.
425
566
  */
426
567
  createSignedBtcStakingTransaction(stakerBtcInfo: StakerInfo, stakingInput: StakingInputs, unsignedStakingTx: Transaction, inputUTXOs: UTXO[], stakingParamsVersion: number): Promise<Transaction>;
568
+ /**
569
+ * Creates a signed staking expansion transaction that is ready to be sent to
570
+ * the BTC network.
571
+ *
572
+ * @param {StakerInfo} stakerBtcInfo - The staker's BTC information including
573
+ * address and public key
574
+ * @param {StakingInputs} stakingInput - The staking inputs for the expansion
575
+ * @param {Transaction} unsignedStakingExpansionTx - The unsigned staking
576
+ * expansion transaction
577
+ * @param {UTXO[]} inputUTXOs - Available UTXOs for the funding input
578
+ * @param {number} stakingParamsVersion - The version of staking parameters
579
+ * that was used when registering the staking expansion delegation.
580
+ * @param {Object} previousStakingTxInfo - Information about the previous
581
+ * staking transaction
582
+ * @param {Array} covenantStakingExpansionSignatures - Covenant committee
583
+ * signatures for the expansion
584
+ * @returns {Promise<Transaction>} The fully signed staking expansion
585
+ * transaction
586
+ * @throws {Error} If signing fails, validation fails, or required data is
587
+ * missing
588
+ */
589
+ createSignedBtcStakingExpansionTransaction(stakerBtcInfo: StakerInfo, stakingInput: StakingInputs, unsignedStakingExpansionTx: Transaction, inputUTXOs: UTXO[], stakingParamsVersion: number, previousStakingTxInfo: {
590
+ stakingTx: Transaction;
591
+ paramVersion: number;
592
+ stakingInput: StakingInputs;
593
+ }, covenantStakingExpansionSignatures: {
594
+ btcPkHex: string;
595
+ sigHex: string;
596
+ }[]): Promise<Transaction>;
427
597
  /**
428
598
  * Creates a partial signed unbonding transaction that is only signed by the
429
599
  * staker. In order to complete the unbonding transaction, the covenant
@@ -505,7 +675,7 @@ export declare class BabylonBtcStakingManager {
505
675
  * @param bech32Address - The staker's bech32 address.
506
676
  * @returns The proof of possession.
507
677
  */
508
- createProofOfPossession(channel: "delegation:create" | "delegation:register", bech32Address: string, stakerBtcAddress: string): Promise<ProofOfPossessionBTC>;
678
+ createProofOfPossession(channel: "delegation:create" | "delegation:register" | "delegation:expand", bech32Address: string, stakerBtcAddress: string): Promise<ProofOfPossessionBTC>;
509
679
  /**
510
680
  * Creates the unbonding, slashing, and unbonding slashing transactions and
511
681
  * PSBTs.
@@ -525,12 +695,22 @@ export declare class BabylonBtcStakingManager {
525
695
  * @param stakerBtcInfo - The staker's BTC information such as address and
526
696
  * public key
527
697
  * @param params - The staking parameters.
528
- * @param inclusionProof - The inclusion proof of the staking transaction.
698
+ * @param options - The options for the BTC delegation.
699
+ * @param options.inclusionProof - The inclusion proof of the staking
700
+ * transaction.
701
+ * @param options.delegationExpansionInfo - The information for the BTC
702
+ * delegation expansion.
529
703
  * @returns The protobuf message.
530
704
  */
531
- createBtcDelegationMsg(channel: "delegation:create" | "delegation:register", stakingInstance: Staking, stakingInput: StakingInputs, stakingTx: Transaction, bech32Address: string, stakerBtcInfo: StakerInfo, params: StakingParams, inclusionProof?: btcstaking.InclusionProof): Promise<{
705
+ createBtcDelegationMsg(channel: "delegation:create" | "delegation:register" | "delegation:expand", stakingInstance: Staking, stakingInput: StakingInputs, stakingTx: Transaction, bech32Address: string, stakerBtcInfo: StakerInfo, params: StakingParams, options?: {
706
+ inclusionProof?: btcstaking.InclusionProof;
707
+ delegationExpansionInfo?: {
708
+ previousStakingTx: Transaction;
709
+ fundingTx: Transaction;
710
+ };
711
+ }): Promise<{
532
712
  typeUrl: string;
533
- value: btcstakingtx.MsgCreateBTCDelegation;
713
+ value: btcstakingtx.MsgCreateBTCDelegation | btcstakingtx.MsgBtcStakeExpand;
534
714
  }>;
535
715
  /**
536
716
  * Gets the inclusion proof for the staking transaction.
@@ -662,6 +842,42 @@ export declare function stakingTransaction(scripts: {
662
842
  slashingScript: Buffer;
663
843
  dataEmbedScript?: Buffer;
664
844
  }, amount: number, changeAddress: string, inputUTXOs: UTXO[], network: networks.Network, feeRate: number, lockHeight?: number): TransactionResult;
845
+ /**
846
+ * Expand an existing staking transaction with additional finality providers
847
+ * or renew timelock.
848
+ *
849
+ * This function builds a Bitcoin transaction that:
850
+ * 1. Spends the previous staking transaction output as the first input
851
+ * 2. Uses a funding UTXO as the second input to cover transaction fees
852
+ * 3. Creates new staking outputs where the timelock is renewed or FPs added
853
+ * 4. Returns any remaining funds as change
854
+ *
855
+ * @param network - Bitcoin network (mainnet, testnet, etc.)
856
+ * @param scripts - Scripts for the new staking outputs
857
+ * @param amount - Total staking amount (must equal previous staking amount,
858
+ * we only support equal amounts for now)
859
+ * @param changeAddress - Bitcoin address to receive change from funding UTXO
860
+ * @param feeRate - Fee rate in satoshis per byte
861
+ * @param inputUTXOs - Available UTXOs to use for funding the expansion
862
+ * @param previousStakingTxInfo - Details of the previous staking transaction
863
+ * being expanded
864
+ * @returns {TransactionResult & { fundingUTXO: UTXO }} containing the built
865
+ * transaction and calculated fee, and the funding UTXO
866
+ */
867
+ export declare function stakingExpansionTransaction(network: networks.Network, scripts: {
868
+ timelockScript: Buffer;
869
+ unbondingScript: Buffer;
870
+ slashingScript: Buffer;
871
+ }, amount: number, changeAddress: string, feeRate: number, inputUTXOs: UTXO[], previousStakingTxInfo: {
872
+ stakingTx: Transaction;
873
+ scripts: {
874
+ timelockScript: Buffer;
875
+ unbondingScript: Buffer;
876
+ slashingScript: Buffer;
877
+ };
878
+ }): TransactionResult & {
879
+ fundingUTXO: UTXO;
880
+ };
665
881
  /**
666
882
  * Constructs a withdrawal transaction for manually unbonded delegation.
667
883
  *
@@ -980,39 +1196,40 @@ export declare const deriveSlashingOutput: (scripts: {
980
1196
  */
981
1197
  export declare const findMatchingTxOutputIndex: (tx: Transaction, outputAddress: string, network: networks.Network) => number;
982
1198
  /**
983
- * Validate the staking transaction input data.
1199
+ * toBuffers converts an array of strings to an array of buffers.
984
1200
  *
985
- * @param {number} stakingAmountSat - The staking amount in satoshis.
986
- * @param {number} timelock - The staking time in blocks.
987
- * @param {StakingParams} params - The staking parameters.
988
- * @param {UTXO[]} inputUTXOs - The input UTXOs.
989
- * @param {number} feeRate - The Bitcoin fee rate in sat/vbyte
990
- * @throws {StakingError} - If the input data is invalid.
1201
+ * @param {string[]} inputs - The input strings.
1202
+ * @returns {Buffer[]} - The buffers.
1203
+ * @throws {StakingError} - If the values cannot be converted to buffers.
991
1204
  */
992
- export declare const validateStakingTxInputData: (stakingAmountSat: number, timelock: number, params: StakingParams, inputUTXOs: UTXO[], feeRate: number) => void;
1205
+ export declare const toBuffers: (inputs: string[]) => Buffer[];
993
1206
  /**
994
- * Validate the staking parameters.
995
- * Extend this method to add additional validation for staking parameters based
996
- * on the staking type.
997
- * @param {StakingParams} params - The staking parameters.
998
- * @throws {StakingError} - If the parameters are invalid.
1207
+ * Strips all signatures from a transaction by clearing both the script and
1208
+ * witness data. This is due to the fact that we only need the raw unsigned
1209
+ * transaction structure. The signatures are sent in a separate protobuf field
1210
+ * when creating the delegation message in the Babylon.
1211
+ * @param tx - The transaction to strip signatures from
1212
+ * @returns A copy of the transaction with all signatures removed
999
1213
  */
1000
- export declare const validateParams: (params: StakingParams) => void;
1214
+ export declare const clearTxSignatures: (tx: Transaction) => Transaction;
1001
1215
  /**
1002
- * Validate the staking timelock.
1003
- *
1004
- * @param {number} stakingTimelock - The staking timelock.
1005
- * @param {StakingParams} params - The staking parameters.
1006
- * @throws {StakingError} - If the staking timelock is invalid.
1216
+ * Derives the merkle proof from the list of hex strings. Note the
1217
+ * sibling hashes are reversed from hex before concatenation.
1218
+ * @param merkle - The merkle proof hex strings.
1219
+ * @returns The merkle proof in hex string format.
1007
1220
  */
1008
- export declare const validateStakingTimelock: (stakingTimelock: number, params: StakingParams) => void;
1221
+ export declare const deriveMerkleProof: (merkle: string[]) => string;
1009
1222
  /**
1010
- * toBuffers converts an array of strings to an array of buffers.
1223
+ * Extracts the first valid Schnorr signature from a signed transaction.
1011
1224
  *
1012
- * @param {string[]} inputs - The input strings.
1013
- * @returns {Buffer[]} - The buffers.
1014
- * @throws {StakingError} - If the values cannot be converted to buffers.
1225
+ * Since we only handle transactions with a single input and request a signature
1226
+ * for one public key, there can be at most one signature from the Bitcoin node.
1227
+ * A valid Schnorr signature is exactly 64 bytes in length.
1228
+ *
1229
+ * @param singedTransaction - The signed Bitcoin transaction to extract the signature from
1230
+ * @returns The first valid 64-byte Schnorr signature found in the transaction witness data,
1231
+ * or undefined if no valid signature exists
1015
1232
  */
1016
- export declare const toBuffers: (inputs: string[]) => Buffer[];
1233
+ export declare const extractFirstSchnorrSignatureFromTransaction: (singedTransaction: Transaction) => Buffer | undefined;
1017
1234
 
1018
1235
  export {};