Skip to main content
Glama

send_onchain

Send Bitcoin payments directly on-chain to any Bitcoin address using the Strike wallet. Specify the recipient address and amount in satoshis to complete transactions.

Instructions

Send an on-chain Bitcoin payment to a Bitcoin address. Currently only available with Strike wallet.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
addressYesBitcoin address to send to (e.g., bc1q...)
amount_satsYesAmount to send in satoshis

Implementation Reference

  • The main handler function for the `send_onchain` MCP tool. It validates inputs, checks wallet compatibility, performs budget authorization, delegates the actual transaction to the wallet (LND or Strike), records the spend, and formats the result.
    async def send_onchain(
        address: str,
        amount_sats: int,
        wallet: "Union[StrikeWallet, LndWallet, None]" = None,
        budget_service: "BudgetService | None" = None,
    ) -> str:
        """
        Send an on-chain Bitcoin payment to a Bitcoin address.
    
        Supports Strike and LND wallets. The payment is sent from your
        wallet balance.
    
        Args:
            address: Bitcoin address to send to (e.g., bc1q...)
            amount_sats: Amount to send in satoshis
            wallet: Strike or LND wallet instance
            budget_service: BudgetService for spending limits
    
        Returns:
            JSON with payment result including transaction details
        """
        if not address or not address.strip():
            return json.dumps({
                "success": False,
                "error": "Bitcoin address is required"
            })
    
        if amount_sats <= 0:
            return json.dumps({
                "success": False,
                "error": "Amount must be greater than 0 sats"
            })
    
        if not wallet:
            return json.dumps({
                "success": False,
                "error": "Wallet not configured. Set STRIKE_API_KEY or LND_REST_HOST+LND_MACAROON_HEX for on-chain payments."
            })
    
        # Verify it's a supported wallet type
        from ..strike_wallet import StrikeWallet
        from ..lnd_wallet import LndWallet
        if not isinstance(wallet, (StrikeWallet, LndWallet)):
            provider_name = type(wallet).__name__.replace("Wallet", "")
            return json.dumps({
                "success": False,
                "error": f"{provider_name} does not support on-chain payments. Use Strike or LND wallet.",
                "errorCode": "NOT_SUPPORTED",
                "hint": "Set STRIKE_API_KEY or LND_REST_HOST+LND_MACAROON_HEX for on-chain payments."
            })
    
        # Check budget if configured
        if budget_service:
            try:
                budget_result = await budget_service.check_approval_level(amount_sats)
                from ..config import ApprovalLevel
                if budget_result.level == ApprovalLevel.DENY:
                    return json.dumps({
                        "success": False,
                        "error": f"Budget check failed: {budget_result.denial_reason}",
                    })
            except Exception as e:
                logger.warning(f"Budget check failed: {e}")
    
        try:
            result = await wallet.send_onchain(address.strip(), amount_sats)
    
            if not result.success:
                return json.dumps({
                    "success": False,
                    "error": result.error_message,
                    "errorCode": result.error_code,
                })
    
            # Record spend if budget service available
            if budget_service:
                try:
                    total_sats = amount_sats + (result.fee_sats or 0)
                    budget_service.record_spend(total_sats)
                    budget_service.record_payment_time()
                except Exception:
                    pass
    
            provider_name = "LND" if isinstance(wallet, LndWallet) else "Strike"
    
            if result.state == "COMPLETED":
                message = f"On-chain payment of {amount_sats} sats sent to {address}"
            else:
                message = f"On-chain payment initiated (status: {result.state})"
    
            return json.dumps({
                "success": True,
                "provider": provider_name,
                "payment": {
                    "id": result.payment_id,
                    "txId": result.txid,
                    "state": result.state,
                    "amountSats": result.amount_sats,
                    "feeSats": result.fee_sats,
                },
                "message": message,
            }, indent=2)
    
        except Exception as e:
            logger.exception("Error sending on-chain payment")
            return json.dumps({
                "success": False,
                "error": sanitize_error(str(e))
            })

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/refined-element/lightning-enable-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server