BitHive SDK for Bitcoin Staking
import {
validateDepositInTransaction,
buildUnsignedDepositPsbt,
CommonUtxo,
DepositMetadata,
H256,
PublicKey,
} from '@bithive/bitcoin-sdk';
import * as bitcoin from 'bitcoinjs-lib';
// Testnet
const network = bitcoin.networks.testnet;
// User public key, address and script
const userPublicKey = PublicKey.fromHex('032b8...8e363');
const userAddress = 'tb1qn...fsk27'; // Native Segwit address
const userScript = bitcoin.address.toOutputScript(userAddress, network);
// Deposit amount
const depositAmount = 2500;
// Fee rate of deposit transaction
const depositFeeRate = 2;
// Following values are just examples, please fetch from BitHive contract
// Chain Signatures public key
const chainSignaturesPublicKey = PublicKey.fromHex(
'020000000000000000000000000000000000000000000000000000000000000000',
);
// The minimum number of blocks that need to be confirmed before SOLO withdrawal
const soloWithdrawSequenceHeight = 2;
// The earliest block height at which deposits are open
const earliestDepositBlockHeight = 0;
// Deposit metadata
const depositMetadata: DepositMetadata = {
publicKey: userPublicKey,
chainSignaturesPublicKey,
soloWithdrawSequenceHeight,
earliestDepositBlockHeight,
};
// Common UTXOs owned by user
const utxos: CommonUtxo[] = [
{
txHash: H256.fromHex(
'0000000000000000000000000000000000000000000000000000000000000001',
),
vout: 1,
value: 1234,
script: userScript,
},
{
txHash: H256.fromHex(
'0000000000000000000000000000000000000000000000000000000000000002',
),
vout: 2,
value: 2345,
script: userScript,
},
{
txHash: H256.fromHex(
'0000000000000000000000000000000000000000000000000000000000000003',
),
vout: 3,
value: 3456,
script: userScript,
},
{
txHash: H256.fromHex(
'0000000000000000000000000000000000000000000000000000000000000004',
),
vout: 4,
value: 4567,
script: userScript,
},
];
// 1. Build the deposit PSBT
const { psbt, metadata: psbtMetadata } = await buildUnsignedDepositPsbt({
utxos,
amount: depositAmount,
// strategy: 'Greedy', // Specify `strategy` here if needed
// feeLimit: 1000, // Specify `feeLimit` here if needed
feeRate: depositFeeRate,
changeScript: userScript,
metadata: depositMetadata,
network,
});
console.log(psbt, psbtMetadata);
// 2. Sign the deposit PSBT by user
/* Implement here by yourself */
// 3. Finalize the deposit PSBT
psbt.finalizeAllInputs();
// 4. Extract the deposit transaction
const transaction = psbt.extractTransaction();
// 5. Validate the deposit transaction. Don't forget to save the redeem script because it will be used during withdrawals
const { redeemScript } = validateDepositInTransaction({
transaction,
amount: depositAmount,
position: psbtMetadata.position,
metadata: depositMetadata,
network,
});
// 6. Broadcast the transaction
/* Implement here by yourself */
import {
buildUnsignedWithdrawPsbt,
finalizeWithdrawPsbt,
DepositUtxo,
RedepositMetadata,
H256,
PublicKey,
} from '@bithive/bitcoin-sdk';
import * as bitcoin from 'bitcoinjs-lib';
// Testnet
const network = bitcoin.networks.testnet;
// User public key, address and script
const userPublicKey = PublicKey.fromHex('032b8...8e363');
const userAddress = 'tb1qn...fsk27'; // Native Segwit address
const userScript = bitcoin.address.toOutputScript(userAddress, network);
// Withdrawal amount
const withdrawAmount = 1000;
// Fee rate of withdrawal transaction
const withdrawFeeRate = 2;
// Following values are just examples, please fetch from BitHive contract
// Chain Signatures public key
const chainSignaturesPublicKey = PublicKey.fromHex(
'020000000000000000000000000000000000000000000000000000000000000000',
);
// The minimum number of blocks that need to be confirmed before SOLO withdrawal
const soloWithdrawSequenceHeight = 2;
// The earliest block height at which deposits are open
const earliestDepositBlockHeight = 0;
// Redeposit metadata
const redepositMetadata: RedepositMetadata = {
publicKey: userPublicKey,
chainSignaturesPublicKey,
soloWithdrawSequenceHeight,
earliestDepositBlockHeight,
};
// Redeem script
const redeemScript = Buffer.from('6352b...2ae68', 'hex');
// Deposit UTXOs owned by user
const utxos: DepositUtxo[] = [
{
txHash: H256.fromHex(
'0000000000000000000000000000000000000000000000000000000000000000',
),
vout: 0,
value: 2500,
redeemScript,
// soloWithdrawSequenceHeight, // Required by SOLO withdrawal
},
];
// 1. Build the withdrawal PSBT
const { psbt, metadata: psbtMetadata } = await buildUnsignedWithdrawPsbt({
utxos,
amount: withdrawAmount,
// strategy: 'Greedy', // Specify `strategy` here if needed
recipientScript: userScript,
// feeLimit: 1500, // Specify `feeLimit` here if needed
feeRate: withdrawFeeRate,
redepositMetadata,
network,
});
console.log(psbt, psbtMetadata);
// 2. Sign the withdrawal PSBT by user
/* Implement here by yourself */
// 3. Sign the withdrawal PSBT by Chain Signatures. Ignore this if it is a SOLO withdrawal
/* Implement here by yourself */
// 4. Finalize the withdrawal PSBT
finalizeWithdrawPsbt({
psbt,
inputs: psbtMetadata.utxos.map((_utxo, index) => ({
vin: index,
// User partial signature
partialSignature: {
publicKey: userPublicKey,
// Optional: Specify manually if PSBT doesn't contain signature
},
// Chain partial signature. Ignore this if it is a SOLO withdrawal
chainPartialSignature: {
publicKey: chainSignaturesPublicKey,
// Optional: Specify manually if PSBT doesn't contain signature
},
})),
network,
});
// 5. Extract the withdrawal transaction
const transaction = psbt.extractTransaction();
// 6. Broadcast the withdrawal transaction
/* Implement here by yourself */