UNPKG

@bithive/relayer-api

Version:

BitHive Relayer API

193 lines (151 loc) 5.01 kB
# BitHive Relayer API Stake Bitcoin to BitHive with Relayer API. ## Introduction `@bithive/relayer-api` is a library that provides a simple interface for staking Bitcoin to BitHive with minimal efforts. It is designed to be used in the browser and Node.js. It acts as a client for the BitHive Relayer. ## Installation ```shell pnpm install @bithive/relayer-api ``` ## Usage ### Stake Bitcoin ```ts import { createRelayerClient } from '@bithive/relayer-api'; // Create a relayer client const relayer = createRelayerClient({ url: config.relayerRpcUrl }); // User public key (compressed) const publicKey = '0277...288a'; // User address // Supported Address Types // - Native Segwit (P2WPKH) // - Nested Segwit (P2SH-P2WPKH) // - Taproot (P2TR) // - Legacy (P2PKH) const address = 'tb1q...wrh8'; // Bitcoin amount that is within the valid scope // e.g. between 0.005 and 0.1 BTC const amount = 1000000; // 0.01 BTC // BTC provider with `signPsbt` interface const provider = window.unisat; // UniSat wallet // 1. Build the PSBT that is ready for signing const { psbt: unsignedPsbt } = await relayer.deposit.buildUnsignedPsbt({ publicKey, address, amount, // Optional: specify `fee` or `feeRate` here if needed }); // 2. Sign and finalize the PSBT with wallet if (!provider.signPsbt) { throw Error('signPsbt is not supported'); } const signedPsbt = await provider.signPsbt(unsignedPsbt); // 3. Submit the finalized PSBT for broadcasting and relaying await relayer.deposit.submitFinalizedPsbt({ psbt: signedPsbt, }); ``` ### Unstake Bitcoin ```ts import { createRelayerClient } from '@bithive/relayer-api'; // Create a relayer client const relayer = createRelayerClient({ url: config.relayerRpcUrl }); // User public key (compressed) const publicKey = '0277...288a'; // BTC provider with `signMessage` interface const provider = window.unisat; // UniSat wallet // Get the deposits by public key const { deposits } = await relayer.user.getDeposits({ publicKey, }); // Find the first confirmed deposit const confirmedDeposit = deposits.find( (deposit) => ['DepositConfirmed', 'DepositConfirmedInvalid'].includes( deposit.status, ), ); if (!confirmedDeposit) { throw Error('No confirmed deposit that is ready to unstake'); } // 1. Build the unstaking message that is ready for signing const { message } = await relayer.unstake.buildUnsignedMessage({ deposits: [{ txHash: confirmedDeposit.depositTxHash, vout: confirmedDeposit.depositVout, }], publicKey, }); // 2. Sign the unstaking message with wallet if (!provider.signMessage) { throw Error('signMessage is not supported'); } const signature = await provider.signMessage(message); // 3. Submit the unstaking signature and relay to BitHive contract on NEAR await relayer.unstake.submitSignature({ deposits: [{ txHash: confirmedDeposit.depositTxHash, vout: confirmedDeposit.depositVout, }], publicKey, signature: Buffer.from(signature, 'base64').toString('hex'), }); ``` ### Withdraw Bitcoin ```ts import { createRelayerClient } from '@bithive/relayer-api'; // Create a relayer client const relayer = createRelayerClient({ url: config.relayerRpcUrl }); // User public key (compressed) const publicKey = '0277...288a'; // Recipient address (can be different with user address) const recipientAddress = 'tb1q...wrh8'; // BTC provider with `signPsbt` interface const provider = window.unisat; // UniSat wallet // Get the account info by public key const { account } = await relayer.user.getAccount({ publicKey, }); let partiallySignedPsbt: string | undefined = undefined; if (account.pendingSignPsbt) { // If there's a pending PSBT for signing, user cannot request signing a new PSBT partiallySignedPsbt = account.pendingSignPsbt.psbt; } else { // Get the deposits by public key const { deposits } = await relayer.user.getDeposits({ publicKey, }); // Find the first deposit that is ready to withdraw const unstakedDeposit = deposits.find( (deposit) => ['UnstakeConfirmed'].includes(deposit.status), ); // 1. Build the PSBT that is ready for signing const { psbt: unsignedPsbt } = await relayer.withdraw.buildUnsignedPsbt({ deposits: { txHash: unstakedDeposit.depositTxHash, vout: unstakedDeposit.depositVout, }, recipientAddress, publicKey, // Optional: specify `fee` or `feeRate` here if needed }); // 2. Sign the PSBT with wallet. Don't finalize it. if (!provider.signPsbt) { throw Error('signPsbt is not supported'); } partiallySignedPsbt = await provider.signPsbt(unsignedPsbt, { autoFinalized: false, toSignInputs: [{ index: 0, publicKey, }], }); } // 3. Sign the PSBT with NEAR Chain Signatures const { psbt: fullySignedPsbt } = await relayer.withdraw.chainSignPsbt({ psbt: partiallySignedPsbt, }); // 4. Submit the finalized PSBT for broadcasting and relaying await relayer.withdraw.submitFinalizedPsbt({ psbt: fullySignedPsbt, }); ```