invoices: multi-crypto payment support
One asset per invoice from a registry (lib/crypto_asset.rb): BTC, LTC, ETH, XMR, SOL, ALGO, USDT/USDC on ERC-20/TRC-20/BEP-20/Solana/Algorand. Migration 003 generalizes the ltc_* columns to crypto_* + crypto_coin (existing LTC invoices backfilled). QR payload adapts per asset: BIP21 amount URIs where supported, bare address for tokens with a network hint on the PDF. Default addresses come from the CRYPTO_ADDRESSES secret (JSON code=>address); LTC_ADDRESS still works as legacy.
This commit is contained in:
parent
f9c7001e7a
commit
0fbb6ee809
20 changed files with 410 additions and 143 deletions
33
lib/crypto_qr.rb
Normal file
33
lib/crypto_qr.rb
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
require 'rqrcode'
|
||||
require_relative 'crypto_asset'
|
||||
|
||||
# Renders a crypto payment QR as PNG bytes for embedding in the PDF.
|
||||
# The encoded payload depends on the asset (see CryptoAsset): a payment URI
|
||||
# with amount, a bare scheme URI, or just the address.
|
||||
module CryptoQr
|
||||
module_function
|
||||
|
||||
# `amount` is a BigDecimal or nil (address-only QR).
|
||||
def uri(coin, address, amount)
|
||||
asset = CryptoAsset[coin] or return address
|
||||
return address unless asset[:scheme]
|
||||
base = "#{asset[:scheme]}:#{address}"
|
||||
return base if amount.nil? || asset[:amount_param].nil?
|
||||
# Trim trailing zeros so the wallet shows a clean amount; keep up to 8 dp.
|
||||
amt = amount.round(8).to_s('F').sub(/\.?0+$/, '')
|
||||
"#{base}?#{asset[:amount_param]}=#{amt}"
|
||||
end
|
||||
|
||||
# Returns PNG bytes (binary string), sized for a crisp ~120pt PDF placement.
|
||||
def png(coin, address, amount, size: 480)
|
||||
qr = RQRCode::QRCode.new(uri(coin, address, amount), level: :m)
|
||||
qr.as_png(
|
||||
bit_depth: 1,
|
||||
border_modules: 2,
|
||||
color: 'black',
|
||||
fill: 'white',
|
||||
module_px_size: 6,
|
||||
resize_exactly_to: size
|
||||
).to_s
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue