diff options
| author | Your Name <you@example.com> | 2026-05-17 04:37:15 +0530 |
|---|---|---|
| committer | Your Name <you@example.com> | 2026-05-17 04:37:15 +0530 |
| commit | cb4bd7d7c10cadcb43f82c09b13ffed744e541f7 (patch) | |
| tree | 1f01c31083e9252b7f41e89ba201373d6606a47d /components/nucula_lib | |
| parent | 78dd599277b8e8b2ddc39a4ae710ec91d737272e (diff) | |
Phase 5: Lightning auto-payout with LNURL-pay and NUT-05 melt
- New lnurl_pay.c/h: LNURL-pay protocol (GET .well-known/lnurlp + callback)
- New lightning_payout.c/h: threshold-based auto-payout with multi-recipient split
- Extended nucula_wallet bridge with nucula_wallet_melt() (NUT-05)
- Config: payout section with multi-mint, multi-recipient, fee_tolerance
- Default: enabled, TollGate@coinos.io, min_payout=128, min_balance=64
- 18 new unit tests (all passing), 134 total
Diffstat (limited to 'components/nucula_lib')
| -rw-r--r-- | components/nucula_lib/nucula_wallet.cpp | 35 | ||||
| -rw-r--r-- | components/nucula_lib/nucula_wallet.h | 2 |
2 files changed, 37 insertions, 0 deletions
diff --git a/components/nucula_lib/nucula_wallet.cpp b/components/nucula_lib/nucula_wallet.cpp index 50583f9..9a24e89 100644 --- a/components/nucula_lib/nucula_wallet.cpp +++ b/components/nucula_lib/nucula_wallet.cpp | |||
| @@ -197,3 +197,38 @@ void nucula_wallet_print_status(void) | |||
| 197 | proofs[i].amount, proofs[i].id.c_str()); | 197 | proofs[i].amount, proofs[i].id.c_str()); |
| 198 | } | 198 | } |
| 199 | } | 199 | } |
| 200 | |||
| 201 | esp_err_t nucula_wallet_melt(const char *bolt11_invoice, uint64_t max_fee_sats) | ||
| 202 | { | ||
| 203 | if (!s_wallet || !bolt11_invoice) return ESP_FAIL; | ||
| 204 | |||
| 205 | cashu::MeltQuote quote; | ||
| 206 | if (!s_wallet->request_melt_quote(std::string(bolt11_invoice), quote)) { | ||
| 207 | ESP_LOGE(TAG, "Melt quote request failed"); | ||
| 208 | return ESP_FAIL; | ||
| 209 | } | ||
| 210 | |||
| 211 | uint64_t total_cost = (uint64_t)quote.amount + (uint64_t)quote.fee_reserve; | ||
| 212 | if (total_cost > max_fee_sats) { | ||
| 213 | ESP_LOGE(TAG, "Melt cost %llu exceeds max %llu (amount=%d fee=%d)", | ||
| 214 | (unsigned long long)total_cost, (unsigned long long)max_fee_sats, | ||
| 215 | quote.amount, quote.fee_reserve); | ||
| 216 | return ESP_FAIL; | ||
| 217 | } | ||
| 218 | |||
| 219 | int balance_before = s_wallet->balance(); | ||
| 220 | if (balance_before < quote.amount) { | ||
| 221 | ESP_LOGE(TAG, "Insufficient balance: %d < %d", balance_before, quote.amount); | ||
| 222 | return ESP_FAIL; | ||
| 223 | } | ||
| 224 | |||
| 225 | int change_amount = 0; | ||
| 226 | if (!s_wallet->melt_tokens(quote, change_amount)) { | ||
| 227 | ESP_LOGE(TAG, "Melt tokens failed"); | ||
| 228 | return ESP_FAIL; | ||
| 229 | } | ||
| 230 | |||
| 231 | ESP_LOGI(TAG, "Melted: %d sats paid, %d change, balance=%d->%d", | ||
| 232 | quote.amount, change_amount, balance_before, s_wallet->balance()); | ||
| 233 | return ESP_OK; | ||
| 234 | } | ||
diff --git a/components/nucula_lib/nucula_wallet.h b/components/nucula_lib/nucula_wallet.h index 64b7c24..784a126 100644 --- a/components/nucula_lib/nucula_wallet.h +++ b/components/nucula_lib/nucula_wallet.h | |||
| @@ -22,6 +22,8 @@ char *nucula_wallet_proofs_json(void); | |||
| 22 | 22 | ||
| 23 | esp_err_t nucula_wallet_swap_all(void); | 23 | esp_err_t nucula_wallet_swap_all(void); |
| 24 | 24 | ||
| 25 | esp_err_t nucula_wallet_melt(const char *bolt11_invoice, uint64_t max_fee_sats); | ||
| 26 | |||
| 25 | void nucula_wallet_print_status(void); | 27 | void nucula_wallet_print_status(void); |
| 26 | 28 | ||
| 27 | #ifdef __cplusplus | 29 | #ifdef __cplusplus |