### Start Development Server Source: https://github.com/stakingrewards/staking-sdk-babylon-simple-staking/blob/main/README.md Starts the development server for the Bitcoin Staking dApp. This command should be run after configuring the necessary environment variables. ```bash npm run dev ``` -------------------------------- ### Copy Environment File Source: https://github.com/stakingrewards/staking-sdk-babylon-simple-staking/blob/main/README.md Copies the example environment file to a local configuration file. This is the first step in setting up the development environment by creating a file to store local environment variables. ```bash cp .env.example .env.local ``` -------------------------------- ### Get Network Fees API Source: https://github.com/stakingrewards/staking-sdk-babylon-simple-staking/blob/main/docs/WalletIntegration.md Retrieves the recommended transaction fees for the Bitcoin network across different confirmation times. ```APIDOC ## GET /api/v1/fees/recommended ### Description Retrieves the recommended transaction fees for the Bitcoin network across different confirmation times. ### Method GET ### Endpoint /api/v1/fees/recommended ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ``` GET /api/v1/fees/recommended ``` ### Response #### Success Response (200) - **fastestFee** (number) - Fee rate in sat/vB for a transaction to be confirmed very quickly. - **halfHourFee** (number) - Fee rate in sat/vB for a transaction to be confirmed within half an hour. - **hourFee** (number) - Fee rate in sat/vB for a transaction to be confirmed within an hour. - **economyFee** (number) - Fee rate in sat/vB for a transaction to be confirmed in a more economical, slower timeframe. - **minimumFee** (number) - The minimum fee rate in sat/vB the network will accept. #### Response Example ```json { "fastestFee": 10, "halfHourFee": 8, "hourFee": 6, "economyFee": 4, "minimumFee": 1 } ``` #### Error Response (4xx/5xx) - **message** (string) - An error message detailing the failure. #### Error Example ```json { "message": "Failed to retrieve fees" } ``` ``` -------------------------------- ### Implement Custom Wallet Provider for Staking dApp (TypeScript) Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt An abstract wallet provider interface for Bitcoin wallet integrations. This example demonstrates a 'CustomWallet' class that extends 'WalletProvider' and utilizes mempool.space API for blockchain data. ```typescript import { WalletProvider, Network, Fees, UTXO } from "./src/utils/wallet/wallet_provider"; import { getAddressBalance, getTipHeight, getFundingUTXOs, getNetworkFees, pushTx } from "./src/utils/mempool_api"; // Example wallet provider implementation class CustomWallet extends WalletProvider { private walletInfo: { publicKeyHex: string; address: string } | undefined; async connectWallet(): Promise { // Connect to wallet extension/app const result = await window.customWallet.connect(); this.walletInfo = { publicKeyHex: result.publicKey, address: result.address }; return this; } async getWalletProviderName(): Promise { return "Custom Wallet"; } async getAddress(): Promise { if (!this.walletInfo) throw new Error("Wallet not connected"); return this.walletInfo.address; } async getPublicKeyHex(): Promise { if (!this.walletInfo) throw new Error("Wallet not connected"); return this.walletInfo.publicKeyHex; } async signPsbt(psbtHex: string): Promise { if (!this.walletInfo) throw new Error("Wallet not connected"); return await window.customWallet.signPsbt(psbtHex); } async signPsbts(psbtsHexes: string[]): Promise { if (!this.walletInfo) throw new Error("Wallet not connected"); return await window.customWallet.signPsbts(psbtsHexes); } async getNetwork(): Promise { return Network.MAINNET; } async signMessageBIP322(message: string): Promise { if (!this.walletInfo) throw new Error("Wallet not connected"); return await window.customWallet.signMessage(message, "bip322-simple"); } on(eventName: string, callBack: () => void): void { if (eventName === "accountChanged") { window.customWallet.on(eventName, callBack); } } // Use mempool API for blockchain data async getBalance(): Promise { return await getAddressBalance(await this.getAddress()); } async getNetworkFees(): Promise { return await getNetworkFees(); } async pushTx(txHex: string): Promise { return await pushTx(txHex); } async getUtxos(address: string, amount?: number): Promise { return await getFundingUTXOs(address, amount); } async getBTCTipHeight(): Promise { return await getTipHeight(); } async getInscriptions(): Promise> { if (!this.walletInfo) throw new Error("Wallet not connected"); // Implement inscription fetching logic return []; } } // Use the wallet async function useWallet() { const wallet = new CustomWallet(); await wallet.connectWallet(); const address = await wallet.getAddress(); const balance = await wallet.getBalance(); const fees = await wallet.getNetworkFees(); console.log(`Address: ${address}`); console.log(`Balance: ${balance} sats`); console.log(`Fastest fee: ${fees.fastestFee} sat/vB`); } ``` -------------------------------- ### Get User Delegations API Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt Retrieves all staking delegations for a specific user's Bitcoin public key, with support for pagination. ```APIDOC ## GET /api/getDelegations ### Description Retrieves all staking delegations for a specific user's Bitcoin public key, with support for pagination. ### Method GET ### Endpoint /api/getDelegations ### Query Parameters - **pagination_key** (string) - Optional - The cursor for the next page of results. Leave empty for the first page. - **publicKeyNoCoord** (string) - Required - The user's Bitcoin public key (33-byte compressed, without coordinate prefix). ### Request Example ```json { "pagination_key": "", "publicKeyNoCoord": "02..." } ``` ### Response #### Success Response (200) - **delegations** (array) - List of delegation objects. - **stakingTxHashHex** (string) - The hash of the staking transaction. - **state** (string) - The current state of the delegation (e.g., `active`, `pending`, `unbonding`). - **stakingValueSat** (number) - The amount staked in satoshis. - **finalityProviderPkHex** (string) - The public key of the finality provider. - **stakingTx** (object) - Details of the staking transaction. - **startHeight** (number) - The block height at which staking started. - **timelock** (number) - The timelock in blocks. - **isOverflow** (boolean) - Indicates if the delegation is an overflow. - **unbondingTx** (object|null) - Details of the unbonding transaction, if applicable. - **txHex** (string) - The hex-encoded unbonding transaction. - **pagination** (object) - Pagination information. - **next_key** (string) - The cursor for the next page of results, or null if there are no more pages. #### Response Example ```json { "delegations": [ { "stakingTxHashHex": "...", "state": "active", "stakingValueSat": 50000000, "finalityProviderPkHex": "03...", "stakingTx": { "startHeight": 12345, "timelock": 1000 }, "isOverflow": false, "unbondingTx": null } ], "pagination": { "next_key": "cursor_def456" } } ``` ``` -------------------------------- ### Get Address Balance API Source: https://github.com/stakingrewards/staking-sdk-babylon-simple-staking/blob/main/docs/WalletIntegration.md Retrieves the total balance of a given Bitcoin address. The balance is returned in satoshis. ```APIDOC ## GET /api/address/{address} ### Description Retrieves the total balance of a given Bitcoin address. The balance is returned in satoshis. ### Method GET ### Endpoint /api/address/{address} ### Parameters #### Path Parameters - **address** (string) - Required - The Bitcoin address to query. #### Query Parameters None #### Request Body None ### Request Example ``` GET /api/address/bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq ``` ### Response #### Success Response (200) - **balance** (number) - The balance of the address in satoshis. #### Response Example ```json { "chain_stats": { "funded_txo_sum": 5000000, "spent_txo_sum": 2000000 }, "mempool_stats": { "funded_txo_sum": 0, "spent_txo_sum": 0 } } ``` #### Error Response (4xx/5xx) - **message** (string) - An error message detailing the failure. #### Error Example ```json { "message": "Address not found" } ``` ``` -------------------------------- ### Get Current Global Parameters Version (TypeScript) Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt This utility function retrieves the current active global parameters version based on the current block height and a list of all available versions. It handles cases where no version is active and provides information about the next approaching version. Dependencies include functions to fetch global parameters and the current tip height from the mempool API. ```typescript import { getCurrentGlobalParamsVersion } from "./src/utils/globalParams"; import { getGlobalParams } from "./src/app/api/getGlobalParams"; import { getTipHeight } from "./src/utils/mempool_api"; // Get current active global parameters async function getCurrentParams() { try { const allVersions = await getGlobalParams(); const currentHeight = await getTipHeight(); const paramsContext = getCurrentGlobalParamsVersion(currentHeight, allVersions); if (!paramsContext.currentVersion) { console.log("No active version at current height"); console.log(`First activation height: ${paramsContext.firstActivationHeight}`); return; } const current = paramsContext.currentVersion; console.log("Current Global Parameters:"); console.log(`Version: ${current.version}`); console.log(`Active since height: ${current.activationHeight}`); console.log(`Min stake: ${current.minStakingAmountSat} sats`); console.log(`Max stake: ${current.maxStakingAmountSat} sats`); console.log(`Staking cap: ${current.stakingCapSat} sats`); if (paramsContext.isApprochingNextVersion && paramsContext.nextVersion) { console.log("\n⚠️ Next version approaching:"); console.log(`Next version: ${paramsContext.nextVersion.version}`); console.log(`Activates at height: ${paramsContext.nextVersion.activationHeight}`); } return paramsContext; } catch (error) { console.error("Error getting current params:", error.message); throw error; } } ``` -------------------------------- ### Get Finality Providers API Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt Fetches a paginated list of finality providers, including their commission rates, total value locked (TVL), and delegation counts. Supports sorting by active TVL. ```APIDOC ## GET /api/getFinalityProviders ### Description Fetches a paginated list of finality providers with their commission rates, total value locked (TVL), and delegation counts. Supports sorting by active TVL. ### Method GET ### Endpoint /api/getFinalityProviders ### Query Parameters - **pagination_key** (string) - Optional - The cursor for the next page of results. Leave empty for the first page. - **sort_field** (string) - Optional - The field to sort the results by. Example: `active_tvl`. ### Request Example ```json { "pagination_key": "", "sort_field": "active_tvl" } ``` ### Response #### Success Response (200) - **finalityProviders** (array) - List of finality provider objects. - **description.moniker** (string) - The moniker of the finality provider. - **btcPk** (string) - The Bitcoin public key of the finality provider. - **commission** (string) - The commission rate charged by the provider. - **activeTVLSat** (number) - The total active value locked in satoshis. - **activeDelegations** (number) - The number of active delegations. - **description.website** (string) - The website URL of the provider. - **pagination** (object) - Pagination information. - **next_key** (string) - The cursor for the next page of results, or null if there are no more pages. #### Response Example ```json { "finalityProviders": [ { "description": { "moniker": "Example Provider", "website": "https://example.com" }, "btcPk": "03...", "commission": "5%", "activeTVLSat": 100000000, "activeDelegations": 50 } ], "pagination": { "next_key": "cursor_abc123" } } ``` ``` -------------------------------- ### Get UTXOs API Source: https://github.com/stakingrewards/staking-sdk-babylon-simple-staking/blob/main/docs/WalletIntegration.md Retrieves the Unspent Transaction Outputs (UTXOs) for a given Bitcoin address. Optionally filters UTXOs to satisfy a specific amount. ```APIDOC ## GET /api/address/{address}/utxo ### Description Retrieves the Unspent Transaction Outputs (UTXOs) for a given Bitcoin address. Optionally filters UTXOs to satisfy a specific amount. ### Method GET ### Endpoint /api/address/{address}/utxo ### Parameters #### Path Parameters - **address** (string) - Required - The Bitcoin address to query. #### Query Parameters - **amount** (number) - Optional - The target amount in satoshis that the UTXOs should satisfy. #### Request Body None ### Request Example ``` GET /api/address/bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq/utxo?amount=10000 ``` ### Response #### Success Response (200) - **utxos** (array) - A list of UTXO objects, each containing `txid`, `vout`, `value`, and `status`. - **txid** (string) - The transaction ID of the UTXO. - **vout** (number) - The output index of the UTXO. - **value** (number) - The value of the UTXO in satoshis. - **status** (object) - Information about the UTXO's confirmation status. - **confirmed** (boolean) - Whether the UTXO is confirmed. - **block_height** (number) - The block height of confirmation. - **block_hash** (string) - The hash of the confirmation block. - **block_time** (number) - The timestamp of the confirmation block. #### Response Example ```json [ { "txid": "a1b2c3d4e5f6...", "vout": 0, "value": 5000000, "status": { "confirmed": true, "block_height": 789012, "block_hash": "0000000000000000000abcde...", "block_time": 1678886400 } } ] ``` #### Error Response (4xx/5xx) - **message** (string) - An error message detailing the failure. #### Error Example ```json { "message": "Address not found or has no UTXOs" } ``` ``` -------------------------------- ### Implement and Inject Mobile Wallet Provider (TypeScript) Source: https://github.com/stakingrewards/staking-sdk-babylon-simple-staking/blob/main/docs/WalletIntegration.md Defines a TypeScript class `MobileAppWallet` that extends `WalletProvider` and demonstrates how to instantiate and inject it into the `window.btcwallet` global object before the Babylon dApp loads. This enables mobile wallet functionality within the dApp. ```typescript class MobileAppWallet extends WalletProvider { ... Interface Methods definitions ... } // Create an instance of the class const wallet = new MobileAppWallet(); // Inject it under the `window.btcwallet` object before the Babylon dApp loads window.btcwallet = wallet; ``` -------------------------------- ### OKX Wallet Integration (TypeScript) Source: https://github.com/stakingrewards/staking-sdk-babylon-simple-staking/blob/main/docs/WalletIntegration.md This TypeScript code defines the `OKXWallet` class, which implements the `WalletProvider` interface for integrating with the OKX Wallet. It handles wallet connection, signing operations, and fetching blockchain data via mempool.space API. Dependencies include the `WalletProvider`, `Network`, `Fees`, `UTXO` types and functions from `../../mempool_api`. ```typescript import { WalletProvider, Network, Fees, UTXO } from "../wallet_provider"; import { getAddressBalance, getTipHeight, getFundingUTXOs, getNetworkFees, pushTx, } from "../../mempool_api"; type OKXWalletInfo = { publicKeyHex: string; address: string; }; export class OKXWallet extends WalletProvider { private okxWalletInfo: OKXWalletInfo | undefined; constructor() { super(); } connectWallet = async (): Promise => { const okxwallet = window.okxwallet; try { await okxwallet.enable(); // Connect to OKX Wallet extension } catch (error) { if ((error as Error)?.message?.includes("rejected")) { throw new Error("Connection to OKX Wallet was rejected"); } else { throw new Error((error as Error)?.message); } } let result = null; try { // this will not throw an error even if user has no BTC Signet enabled result = await okxwallet?.bitcoinSignet?.connect(); } catch (error) { throw new Error("BTC Signet is not enabled in OKX Wallet"); } const { address, compressedPublicKey } = result; if (compressedPublicKey && address) { this.okxWalletInfo = { publicKeyHex: compressedPublicKey, address, }; return this; } else { throw new Error("Could not connect to OKX Wallet"); } }; getWalletProviderName = async (): Promise => { return "OKX"; }; getAddress = async (): Promise => { if (!this.okxWalletInfo) { throw new Error("OKX Wallet not connected"); } return this.okxWalletInfo.address; }; getPublicKeyHex = async (): Promise => { if (!this.okxWalletInfo) { throw new Error("OKX Wallet not connected"); } return this.okxWalletInfo.publicKeyHex; }; signPsbt = async (psbtHex: string): Promise => { if (!this.okxWalletInfo) { throw new Error("OKX Wallet not connected"); } // sign the PSBT return (await this.signPsbts([psbtHex]))[0]; }; signPsbts = async (psbtsHexes: string[]): Promise => { if (!this.okxWalletInfo) { throw new Error("OKX Wallet not connected"); } // sign the PSBTs return await window?.okxwallet?.bitcoinSignet?.signPsbts(psbtsHexes); }; signMessageBIP322 = async (message: string): Promise => { if (!this.okxWalletInfo) { throw new Error("OKX Wallet not connected"); } return await window?.okxwallet?.bitcoinSignet?.signMessage( message, "bip322-simple", ); }; getNetwork = async (): Promise => { return "testnet"; }; on = (eventName: string, callBack: () => void) => { if (!this.okxWalletInfo) { throw new Error("OKX Wallet not connected"); } // subscribe to account change event if (eventName === "accountChanged") { return window.okxwallet.bitcoinSignet.on(eventName, callBack); } }; // Mempool calls getBalance = async (): Promise => { return await getAddressBalance(await this.getAddress()); }; getNetworkFees = async (): Promise => { return await getNetworkFees(); }; pushTx = async (txHex: string): Promise => { return await pushTx(txHex); }; getUtxos = async (address: string, amount?: number): Promise => { // mempool call return await getFundingUTXOs(address, amount); }; getBTCTipHeight = async (): Promise => { return await getTipHeight(); }; getInscriptions = async (): Promise => { if (!this.okxWalletInfo) { throw new Error("OKX Wallet not connected"); } // max num of iterations to prevent infinite loop const MAX_ITERATIONS = 100; // Fetch inscriptions in batches of 100 const limit = 100; const inscriptionIdentifiers: InscriptionIdentifier[] = []; let cursor = 0; let iterations = 0; try { while (iterations < MAX_ITERATIONS) { const { list } = await this.bitcoinNetworkProvider.getInscriptions( cursor, limit, ); const identifiers = list.map((i: { output: string }) => { const [txid, vout] = i.output.split(":"); return { txid, vout, }; }); inscriptionIdentifiers.push(...identifiers); if (list.length < limit) { break; } cursor += limit; iterations++; if (iterations >= MAX_ITERATIONS) { throw new Error( "Exceeded maximum iterations when fetching inscriptions", ); } } } catch (error) { // Error handling can be added here if needed } return inscriptionIdentifiers; }; } ``` -------------------------------- ### Abstract WalletProvider Class for Wallet Interactions Source: https://github.com/stakingrewards/staking-sdk-babylon-simple-staking/blob/main/docs/WalletIntegration.md Defines the abstract WalletProvider class, outlining core functionalities for interacting with cryptocurrency wallets. It includes methods for connecting, retrieving wallet details, signing transactions (PSBTs and messages), managing network information, and handling events. Implementations will vary based on the specific wallet being integrated. ```typescript /** * Abstract class representing a wallet provider. * Provides methods for connecting to a wallet, retrieving wallet information, signing transactions, and more. */ export abstract class WalletProvider { /** * Connects to the wallet and returns the instance of the wallet provider. * Currently only supports "native segwit" and "taproot" address types. * @returns A promise that resolves to an instance of the wrapper wallet provider in babylon friendly format. * @throws An error if the wallet is not installed or if connection fails. */ abstract connectWallet(): Promise; /** * Gets the name of the wallet provider. * @returns A promise that resolves to the name of the wallet provider. */ abstract getWalletProviderName(): Promise; /** * Gets the address of the connected wallet. * @returns A promise that resolves to the address of the connected wallet. */ abstract getAddress(): Promise; /** * Gets the public key of the connected wallet. * @returns A promise that resolves to the public key of the connected wallet. */ abstract getPublicKeyHex(): Promise; /** * Signs the given PSBT in hex format. * @param psbtHex - The hex string of the unsigned PSBT to sign. * @returns A promise that resolves to the hex string of the signed PSBT. */ abstract signPsbt(psbtHex: string): Promise; /** * Signs multiple PSBTs in hex format. * @param psbtsHexes - The hex strings of the unsigned PSBTs to sign. * @returns A promise that resolves to an array of hex strings, each representing a signed PSBT. */ abstract signPsbts(psbtsHexes: string[]): Promise; /** * Gets the network of the current account. * @returns A promise that resolves to the network of the current account. */ abstract getNetwork(): Promise; /** * Signs a message using BIP-322 simple. * @param message - The message to sign. * @returns A promise that resolves to the signed message. */ abstract signMessageBIP322(message: string): Promise; /** * Registers an event listener for the specified event. * At the moment, only the "accountChanged" event is supported. * @param eventName - The name of the event to listen for. * @param callBack - The callback function to be executed when the event occurs. */ abstract on(eventName: string, callBack: () => void): void; /** * Gets the balance for the connected wallet address. * By default, this method will return the mempool balance if not implemented by the child class. * @returns A promise that resolves to the balance of the wallet. */ abstract getBalance(): Promise; /** * Retrieves the network fees. * @returns A promise that resolves to the network fees. */ abstract getNetworkFees(): Promise; /** * Pushes a transaction to the network. * @param txHex - The hexadecimal representation of the transaction. * @returns A promise that resolves to a string representing the transaction ID. */ abstract pushTx(txHex: string): Promise; /** * Retrieves the unspent transaction outputs (UTXOs) for a given address and amount. * If the amount is provided, it will return UTXOs that cover the specified amount. * If the amount is not provided, it will return all available UTXOs for the address. * * @param address - The address to retrieve UTXOs for. * @param amount - Optional amount of funds required. * @returns A promise that resolves to an array of UTXOs. */ abstract getUtxos(address: string, amount?: number): Promise; /** * Retrieves the tip height of the BTC chain. * @returns A promise that resolves to the block height. */ // abstract getBlockHeight(): Promise; } ``` -------------------------------- ### Fetching Recommended Bitcoin Network Fees Source: https://github.com/stakingrewards/staking-sdk-babylon-simple-staking/blob/main/docs/WalletIntegration.md This function fetches the recommended fees for Bitcoin transactions from the mempool.space API. It returns a promise that resolves to a `Fees` object, which contains fee recommendations for different confirmation targets. No specific input is required, and it relies on the `networkFeesUrl` function for the API endpoint. ```typescript /** * Retrieve the recommended Bitcoin network fees. * @returns A promise that resolves into a `Fees` object. */ export async function getNetworkFees(): Promise { const response = await fetch(networkFeesUrl()); if (!response.ok) { const err = await response.text(); throw new Error(err); } else { return await response.json(); } } ``` -------------------------------- ### Fetch User Delegations (TypeScript) Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt Retrieves all staking delegations for a given user's Bitcoin public key with pagination. Uses the Babylon API and requires a 33-byte compressed Bitcoin public key. Outputs delegation details including staking transaction, state, amount, and unbonding information. ```typescript import { getDelegations } from "./src/app/api/getDelegations"; // Fetch user delegations async function fetchUserDelegations(publicKeyNoCoord: string) { try { const { delegations, pagination } = await getDelegations( "", // pagination key publicKeyNoCoord // user's public key (33-byte compressed, without coordinate prefix) ); // Process delegations delegations.forEach(delegation => { console.log(`Staking TX: ${delegation.stakingTxHashHex}`); console.log(`State: ${delegation.state}`); // active, pending, unbonding, etc. console.log(`Amount: ${delegation.stakingValueSat} satoshis`); console.log(`Finality Provider: ${delegation.finalityProviderPkHex}`); console.log(`Start Height: ${delegation.stakingTx.startHeight}`); console.log(`Timelock: ${delegation.stakingTx.timelock} blocks`); console.log(`Is Overflow: ${delegation.isOverflow}`); if (delegation.unbondingTx) { console.log(`Unbonding TX: ${delegation.unbondingTx.txHex}`); } }); } catch (error) { console.error("Error fetching delegations:", error.message); } } ``` -------------------------------- ### URL Construction for mempool.space API Source: https://github.com/stakingrewards/staking-sdk-babylon-simple-staking/blob/main/docs/WalletIntegration.md These functions construct the necessary URLs for interacting with the mempool.space API endpoints. They utilize an environment variable to specify the base API URL and include specific paths for different operations like address info, transaction details, and fee recommendations. No external dependencies are required beyond standard URL construction. ```typescript import { Fees, UTXO } from "./wallet/wallet_provider"; /* URL Construction methods */ // The base URL for the signet API // Utilises an environment variable specifying the mempool API we intend to // utilise const mempoolAPI = `${getNetworkConfig().mempoolApiUrl}/api/`; // URL for the address info endpoint function addressInfoUrl(address: string): URL { return new URL(mempoolAPI + "address/" + address); } // URL for the transactions info endpoint function txInfoUrl(txid: string): URL { return new URL(mempoolAPI + "tx/" + txid); } // URL for the push transaction endpoint function pushTxUrl(): URL { return new URL(mempoolAPI + "tx"); } // URL for retrieving information about an address' UTXOs function utxosInfoUrl(address: string): URL { return new URL(mempoolAPI + "address/" + address + "/utxo"); } // URL for retrieving information about the recommended network fees function networkFeesUrl(): URL { return new URL(mempoolAPI + "v1/fees/recommended"); } ``` -------------------------------- ### Manage Bitcoin Network Configurations Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt Utility functions for setting up and validating network configurations for different Bitcoin networks. It allows retrieval of network settings and validation of Bitcoin addresses against the current network. Dependencies include network.config and wallet_provider modules. ```typescript import { getNetworkConfig, validateAddress, network } from "./src/config/network.config"; import { Network } from "./src/utils/wallet/wallet_provider"; // Get network configuration function setupNetwork() { const config = getNetworkConfig(); console.log("Current Network Configuration:"); console.log(`Network: ${config.network}`); console.log(`Coin: ${config.coinName} (${config.coinSymbol})`); console.log(`Mempool API: ${config.mempoolApiUrl}`); console.log(`Babylon API: ${config.babylonApiUrl}`); console.log(`Points API: ${config.pointsApiUrl}`); return config; } // Validate Bitcoin address for current network function checkAddress(address: string) { try { validateAddress(Network.MAINNET, address); console.log(`✓ Valid mainnet address: ${address}`); } catch (error) { console.error(`✗ Invalid address: ${error.message}`); } // Examples: // Mainnet: bc1q... (bech32) or bc1p... (taproot) // Testnet/Signet: tb1q... or tb1p... } // Environment variables setup // Set in .env.local: // NEXT_PUBLIC_STAKING_SDK_BABYLON_NETWORK=mainnet // NEXT_PUBLIC_STAKING_SDK_BABYLON_MEMPOOL_API=https://mempool.space // NEXT_PUBLIC_STAKING_SDK_BABYLON_API_URL=https://staking-api.babylonlabs.io // NEXT_PUBLIC_STAKING_SDK_BABYLON_POINTS_API_URL=https://points.babylonlabs.io ``` -------------------------------- ### Sign and Submit Bitcoin Staking Transaction (TypeScript) Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt Creates, signs, and broadcasts a Bitcoin staking transaction. This function requires a `WalletProvider`, staking amount, staking time, a finality provider public key, and global parameters. It uses helper functions for signing and broadcasting, and includes validation for staking amounts against global parameters. Dependencies include `signStakingTx` and `WalletProvider` from the SDK. ```typescript import { signStakingTx } from "./src/utils/delegations/signStakingTx"; import { WalletProvider } from "./src/utils/wallet/wallet_provider"; import { networks } from "bitcoinjs-lib"; // Sign and broadcast staking transaction async function stakeBitcoin( wallet: WalletProvider, stakingAmount: number, // in satoshis stakingTimeBlocks: number, finalityProviderPubKey: string, globalParams: any ) { try { const address = await wallet.getAddress(); const publicKey = await wallet.getPublicKeyHex(); const network = networks.bitcoin; // or networks.testnet // Get UTXOs and fee rate const utxos = await wallet.getUtxos(address, stakingAmount); const fees = await wallet.getNetworkFees(); const feeRate = fees.fastestFee; // sat/vB // Validate staking parameters if (stakingAmount < globalParams.minStakingAmountSat) { throw new Error(`Minimum staking amount is ${globalParams.minStakingAmountSat} sats`); } if (stakingAmount > globalParams.maxStakingAmountSat) { throw new Error(`Maximum staking amount is ${globalParams.maxStakingAmountSat} sats`); } // Sign and broadcast staking transaction const { stakingTxHex, stakingTerm } = await signStakingTx( wallet, globalParams, stakingAmount, stakingTimeBlocks, finalityProviderPubKey, network, address, publicKey, feeRate, utxos, () => console.log("Waiting for signature..."), () => console.log("Broadcasting transaction...") ); console.log(`Staking transaction broadcasted: ${stakingTxHex}`); console.log(`Staking term: ${stakingTerm} blocks`); return { stakingTxHex, stakingTerm }; } catch (error) { console.error("Staking failed:", error.message); throw error; } } ``` -------------------------------- ### Fetch Staker and Delegation Points using Babylon SDK (TypeScript) Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt Fetches points earned by stakers and their individual delegations using the Babylon points system. Requires importing specific API functions and handles potential errors during fetching. ```typescript import { getStakersPoints, getDelegationPointsByStakingTxHashHexes } from "./src/app/api/getPoints"; // Fetch staker points async function fetchStakerPoints(stakerPublicKeys: string[]) { try { const stakerPoints = await getStakersPoints(stakerPublicKeys); stakerPoints.forEach(staker => { console.log(`Staker: ${staker.staker_btc_pk}`); console.log(`Points: ${staker.points}`); }); return stakerPoints; } catch (error) { console.error("Error fetching staker points:", error.message); throw error; } } // Fetch delegation points async function fetchDelegationPoints(stakingTxHashes: string[]) { try { const delegationPoints = await getDelegationPointsByStakingTxHashHexes(stakingTxHashes); delegationPoints.forEach(dp => { console.log(`Staking TX: ${dp.staking_tx_hash_hex}`); console.log(`Staker Points: ${dp.staker.points}`); console.log(`Finality Provider Points: ${dp.finality_provider.points}`); console.log(`Staking Height: ${dp.staking_height}`); console.log(`Expiry Height: ${dp.expiry_height}`); if (dp.unbonding_height) { console.log(`Unbonding Height: ${dp.unbonding_height}`); } }); return delegationPoints; } catch (error) { console.error("Error fetching delegation points:", error.message); throw error; } } ``` -------------------------------- ### Fetch Finality Providers (TypeScript) Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt Fetches a paginated list of finality providers from the Babylon API, sorted by active TVL. Requires the '@babylonlabs-io/btc-staking-ts' library. Outputs provider details like moniker, commission, and TVL. ```typescript import { getFinalityProviders } from "./src/app/api/getFinalityProviders"; // Fetch finality providers sorted by active TVL async function fetchProviders() { try { const { finalityProviders, pagination } = await getFinalityProviders( "", // pagination key (empty for first page) "active_tvl" // sort field ); // Process finality providers finalityProviders.forEach(fp => { console.log(`Provider: ${fp.description.moniker}`); console.log(`BTC Public Key: ${fp.btcPk}`); console.log(`Commission: ${fp.commission}`); console.log(`Active TVL: ${fp.activeTVLSat} satoshis`); console.log(`Active Delegations: ${fp.activeDelegations}`); console.log(`Website: ${fp.description.website}`); }); // Use pagination.next_key for next page if (pagination.next_key) { const nextPage = await getFinalityProviders(pagination.next_key, "active_tvl"); } } catch (error) { console.error("Error fetching finality providers:", error.message); } } ``` -------------------------------- ### Sign and Submit Unbonding Transaction (TypeScript) Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt Creates and submits an unbonding transaction to initiate early withdrawal of staked Bitcoin. It fetches user delegations, signs the unbonding transaction using a provided function, and then submits it. ```typescript import { signUnbondingTx } from "./src/utils/delegations/signUnbondingTx"; import { getDelegations } from "./src/app/api/getDelegations"; import { networks } from "bitcoinjs-lib"; // Unbond a staking delegation async function unbondDelegation( stakingTxHash: string, publicKeyNoCoord: string, signPsbtFunction: (psbtHex: string) => Promise ) { try { // Fetch user's delegations const { delegations } = await getDelegations("", publicKeyNoCoord); // Sign and submit unbonding transaction const { unbondingTxHex, delegation } = await signUnbondingTx( stakingTxHash, delegations, publicKeyNoCoord, networks.bitcoin, signPsbtFunction, () => console.log("Waiting for unbonding signature..."), () => console.log("Submitting unbonding request...") ); console.log(`Unbonding transaction submitted: ${unbondingTxHex}`); console.log(`Delegation state: ${delegation.state}`); console.log(`Staked amount: ${delegation.stakingValueSat} sats`); return { unbondingTxHex, delegation }; } catch (error) { console.error("Unbonding failed:", error.message); throw error; } } ``` -------------------------------- ### Sign and Broadcast Withdrawal Transaction (TypeScript) Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt Creates and broadcasts a withdrawal transaction to claim unbonded or expired staking funds. It fetches delegations, signs the withdrawal transaction, and then pushes it to the network. ```typescript import { signWithdrawalTx } from "./src/utils/delegations/signWithdrawalTx"; import { getDelegations } from "./src/app/api/getDelegations"; import { WalletProvider } from "./src/utils/wallet/wallet_provider"; import { networks } from "bitcoinjs-lib"; // Withdraw staked funds async function withdrawFunds( stakingTxHash: string, publicKeyNoCoord: string, wallet: WalletProvider ) { try { const address = await wallet.getAddress(); const { delegations } = await getDelegations("", publicKeyNoCoord); // Create sign PSBT function const signPsbt = async (psbtHex: string) => { const signedPsbtHex = await wallet.signPsbt(psbtHex); return Transaction.fromHex(signedPsbtHex); }; // Sign and broadcast withdrawal const { withdrawalTxHex, delegation } = await signWithdrawalTx( stakingTxHash, delegations, publicKeyNoCoord, networks.bitcoin, signPsbt, address, // withdrawal destination address () => wallet.getNetworkFees(), (txHex) => wallet.pushTx(txHex), () => console.log("Waiting for withdrawal signature..."), () => console.log("Broadcasting withdrawal transaction...") ); console.log(`Withdrawal transaction: ${withdrawalTxHex}`); console.log(`Withdrawn amount: ${delegation.stakingValueSat} sats`); return { withdrawalTxHex, delegation }; } catch (error) { console.error("Withdrawal failed:", error.message); throw error; } } ``` -------------------------------- ### Convert Between Bitcoin Units (BTC and Satoshis) Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt Utility functions for seamless conversion between Bitcoin (BTC) and satoshi denominations. It provides functions to convert satoshis to BTC for display purposes and BTC to satoshis for transaction inputs. This module relies on btcConversions. ```typescript import { satoshiToBtc, btcToSatoshi } from "./src/utils/btcConversions"; // Convert between BTC and satoshis function handleConversions() { // Convert satoshis to BTC for display const stakingAmountSats = 100000000; // 100 million sats const stakingAmountBTC = satoshiToBtc(stakingAmountSats); console.log(`${stakingAmountSats} sats = ${stakingAmountBTC} BTC`); // 1 BTC // Convert BTC to satoshis for transactions const userInputBTC = 0.5; const amountInSats = btcToSatoshi(userInputBTC); console.log(`${userInputBTC} BTC = ${amountInSats} sats`); // 50000000 sats // Display formatting const tvlSats = 2500000000; const tvlBTC = satoshiToBtc(tvlSats); console.log(`Total Value Locked: ${tvlBTC.toFixed(8)} BTC`); } ``` -------------------------------- ### Verify UTXOs for Ordinals/Inscriptions (TypeScript) Source: https://context7.com/stakingrewards/staking-sdk-babylon-simple-staking/llms.txt Checks UTXOs to identify which ones contain inscriptions, ordinals, or runes to prevent accidental spending. It filters UTXOs into 'clean' and 'inscription' categories based on verification results. ```typescript import { postVerifyUtxoOrdinals } from "./src/app/api/postFilterOrdinals"; import { UTXO } from "./src/utils/wallet/wallet_provider"; // Filter out UTXOs containing inscriptions async function filterInscriptionUTXOs( utxos: UTXO[], address: string ) { try { // Verify which UTXOs contain inscriptions const utxoInfo = await postVerifyUtxoOrdinals(utxos, address); // Filter to get only clean UTXOs (no inscriptions) const cleanUtxos = utxos.filter(utxo => { const info = utxoInfo.find( info => info.txid === utxo.txid && info.vout === utxo.vout ); return info && !info.inscription; }); // UTXOs with inscriptions const inscriptionUtxos = utxos.filter(utxo => { const info = utxoInfo.find( info => info.txid === utxo.txid && info.vout === utxo.vout ); return info && info.inscription; }); console.log(`Clean UTXOs: ${cleanUtxos.length}`); console.log(`Inscription UTXOs: ${inscriptionUtxos.length}`); return { cleanUtxos, inscriptionUtxos }; } catch (error) { console.error("Error verifying UTXOs:", error.message); throw error; } } ```