PHP code example of nova-carnivore / bolt12-php
1. Go to this page and download the library: Download nova-carnivore/bolt12-php library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
nova-carnivore / bolt12-php example snippets
use Nova\Bitcoin\Bolt12\Decoder;
$offer = Decoder::decode('lno1...'); // Returns Offer object
$invReq = Decoder::decode('lnr1...'); // Returns InvoiceRequest object
$invoice = Decoder::decode('lni1...'); // Returns Invoice object
use Nova\Bitcoin\Bolt12\Encoder;
use Nova\Bitcoin\Bolt12\Signer;
$encoded = Encoder::encodeOffer(
issuerId: $myPublicKeyHex,
description: 'Buy a coffee',
amountMsat: gmp_init(100000),
issuer: 'CoffeeShop',
);
// Returns: 'lno1...'
$invReq = Encoder::encodeInvoiceRequest(
invreqMetadata: bin2hex(random_bytes(32)),
payerId: $myPublicKeyHex,
payerPrivateKey: $myPrivateKeyHex,
offerDescription: 'Buy a coffee',
offerIssuerId: $merchantPubkey,
offerAmountMsat: gmp_init(100000),
);
// Returns: 'lnr1...' (signed with BIP-340 Schnorr)
use Nova\Bitcoin\Bolt12\BlindedPath;
use Nova\Bitcoin\Bolt12\BlindedPayInfo;
use Nova\Bitcoin\Bolt12\OnionMessageHop;
$invoice = Encoder::encodeInvoice(
nodeId: $myNodePubkey,
nodePrivateKey: $myNodePrivkey,
createdAt: gmp_init(time()),
paymentHash: hash('sha256', $preimage),
amountMsat: gmp_init(100000),
invoicePaths: [
new BlindedPath($blindingKey, [
new OnionMessageHop($nodeId, $encryptedData),
]),
],
blindedPayInfo: [
new BlindedPayInfo(
feeBaseMsat: 1000,
feeProportionalMillionths: 100,
cltvExpiryDelta: 144,
htlcMinimumMsat: gmp_init(1000),
htlcMaximumMsat: gmp_init(1000000000),
),
],
);
// Returns: 'lni1...' (signed with BIP-340 Schnorr)
use Nova\Bitcoin\Bolt12\Signer;
$invReq = Decoder::decode('lnr1...');
$valid = Signer::verifyInvoiceRequest($invReq); // Returns bool
$invoice = Decoder::decode('lni1...');
$valid = Signer::verifyInvoice($invoice); // Returns bool
// Encode
$errorBytes = Encoder::encodeInvoiceError(
error: 'Amount too low',
erroneousField: gmp_init(82), // invreq_amount
suggestedValue: '0186a0', // 100000 as tu64 hex
);
// Decode
$invoiceError = Decoder::decodeInvoiceError($errorBytes);
echo $invoiceError->error; // 'Amount too low'
use Nova\Bitcoin\Bolt12\{Decoder, Encoder, Signer, BlindedPath, BlindedPayInfo, OnionMessageHop};
// 1. Merchant creates an offer
$offer = Encoder::encodeOffer(
issuerId: $merchantPubkey,
description: 'Buy a coffee',
amountMsat: gmp_init(100000),
);
$decoded = Decoder::decode($offer);
// 2. Payer creates invoice request (mirrors offer fields)
$invReq = Encoder::encodeInvoiceRequest(
invreqMetadata: bin2hex(random_bytes(32)),
payerId: $payerPubkey,
payerPrivateKey: $payerPrivkey,
offerDescription: $decoded->description,
offerIssuerId: $decoded->issuerId,
offerAmountMsat: $decoded->amountMsat,
);
// 3. Merchant creates and signs invoice
$invoice = Encoder::encodeInvoice(
nodeId: $merchantPubkey,
nodePrivateKey: $merchantPrivkey,
createdAt: gmp_init(time()),
paymentHash: hash('sha256', $preimage),
amountMsat: gmp_init(100000),
invoicePaths: [$blindedPath],
blindedPayInfo: [$payInfo],
);
// 4. Payer verifies invoice signature
$inv = Decoder::decode($invoice);
assert(Signer::verifyInvoice($inv));
use Nova\Bitcoin\Bolt12\Exception\{
Bolt12Exception, // Base exception
DecodeException, // Malformed input
EncodeException, // Missing/invalid fields
SignatureException, // Signature issues
};
try {
$offer = Decoder::decode($bolt12String);
} catch (DecodeException $e) {
// Malformed string or TLV data
} catch (Bolt12Exception $e) {
// Any BOLT 12 error
}
bash
composer