@@ -36,6 +36,9 @@ struct invreq {
3636
3737 /* Optional secret. */
3838 const struct secret * secret ;
39+
40+ /* Fronting nodes to use for invoice. */
41+ const struct pubkey * fronting_nodes ;
3942};
4043
4144static struct command_result * WARN_UNUSED_RESULT
@@ -275,9 +278,12 @@ static struct command_result *found_best_peer(struct command *cmd,
275278 */
276279 if (!best ) {
277280 /* Don't allow bare invoices if they explicitly told us to front */
278- if (od -> fronting_nodes ) {
281+ if (ir -> fronting_nodes ) {
279282 return fail_invreq (cmd , ir ,
280- "Could not find path from payment-fronting-node" );
283+ "Could not find path from %zu nodes (%s%s)" ,
284+ tal_count (ir -> fronting_nodes ),
285+ fmt_pubkey (tmpctx , & ir -> fronting_nodes [0 ]),
286+ tal_count (ir -> fronting_nodes ) > 1 ? ", ..." : "" );
281287 }
282288
283289 /* Note: since we don't make one, createinvoice adds a dummy. */
@@ -390,9 +396,7 @@ static struct command_result *found_best_peer(struct command *cmd,
390396static struct command_result * add_blindedpaths (struct command * cmd ,
391397 struct invreq * ir )
392398{
393- const struct offers_data * od = get_offers_data (cmd -> plugin );
394-
395- if (!we_want_blinded_path (cmd -> plugin , od -> fronting_nodes , true))
399+ if (!we_want_blinded_path (cmd -> plugin , ir -> fronting_nodes , true))
396400 return create_invoicereq (cmd , ir );
397401
398402 /* Technically, this only needs OPT_ROUTE_BLINDING, but we have a report
@@ -401,7 +405,7 @@ static struct command_result *add_blindedpaths(struct command *cmd,
401405 * us onion messaging. */
402406 return find_best_peer (cmd ,
403407 (1ULL << OPT_ROUTE_BLINDING ) | (1ULL << OPT_ONION_MESSAGES ),
404- od -> fronting_nodes , found_best_peer , ir );
408+ ir -> fronting_nodes , found_best_peer , ir );
405409}
406410
407411static struct command_result * cancel_invoice (struct command * cmd ,
@@ -830,6 +834,7 @@ static struct command_result *listoffers_done(struct command *cmd,
830834 struct command_result * err ;
831835 struct amount_msat amt ;
832836 struct tlv_invoice_request_invreq_recurrence_cancel * cancel ;
837+ struct pubkey * offer_fronts ;
833838
834839 /* BOLT #12:
835840 *
@@ -915,6 +920,37 @@ static struct command_result *listoffers_done(struct command *cmd,
915920 return fail_invreq (cmd , ir , "Offer expired" );
916921 }
917922
923+ /* If offer used fronting nodes, we use them too. */
924+ offer_fronts = tal_arr (ir , struct pubkey , 0 );
925+ for (size_t i = 0 ; i < tal_count (ir -> invreq -> offer_paths ); i ++ ) {
926+ const struct blinded_path * p = ir -> invreq -> offer_paths [i ];
927+ struct sciddir_or_pubkey first = p -> first_node_id ;
928+
929+ /* In dev mode we could set this. Ignore if we can't map */
930+ if (!first .is_pubkey && !gossmap_scidd_pubkey (get_gossmap (cmd -> plugin ), & first )) {
931+ plugin_log (cmd -> plugin , LOG_UNUSUAL ,
932+ "Can't find front %s, ignoring in %s" ,
933+ fmt_sciddir_or_pubkey (tmpctx , & p -> first_node_id ),
934+ invrequest_encode (tmpctx , ir -> invreq ));
935+ continue ;
936+ }
937+ assert (first .is_pubkey );
938+ /* Self-paths are not fronting nodes */
939+ if (!pubkey_eq (& od -> id , & first .pubkey ))
940+ tal_arr_expand (& offer_fronts , first .pubkey );
941+ }
942+ if (tal_count (offer_fronts ) != 0 )
943+ ir -> fronting_nodes = offer_fronts ;
944+ else {
945+ /* Get upset if none from offer (via invreq) were usable! */
946+ if (tal_count (ir -> invreq -> offer_paths ) != 0 )
947+ return fail_invreq (cmd , ir , "Fronting failed, could not find any fronts" );
948+
949+ /* Otherwise, use defaults */
950+ tal_free (offer_fronts );
951+ ir -> fronting_nodes = od -> fronting_nodes ;
952+ }
953+
918954 /* BOLT-recurrence #12:
919955 * - if `offer_quantity_max` is present:
920956 * - MUST reject the invoice request if `invreq_recurrence_cancel`
0 commit comments