If it returns NULL, *authorized is the most we agreed to pay. */
| 2160 | |
| 2161 | /* If it returns NULL, *authorized is the most we agreed to pay. */ |
| 2162 | static struct command_result *check_offer_payable(struct command *cmd, |
| 2163 | const char *offerstr, |
| 2164 | const struct amount_msat *msat, |
| 2165 | struct amount_msat *authorized) |
| 2166 | { |
| 2167 | const char *err; |
| 2168 | struct tlv_offer *b12offer = offer_decode(tmpctx, |
| 2169 | offerstr, |
| 2170 | strlen(offerstr), |
| 2171 | plugin_feature_set(cmd->plugin), |
| 2172 | chainparams, &err); |
| 2173 | if (!b12offer) |
| 2174 | return command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
| 2175 | "Invalid bolt12 offer: %s", err); |
| 2176 | /* BOLT #12: |
| 2177 | * - if `offer_amount` is not present: |
| 2178 | * - MUST specify `invreq_amount`. |
| 2179 | * - otherwise: |
| 2180 | * - MAY omit `invreq_amount`. |
| 2181 | * - if it sets `invreq_amount`: |
| 2182 | * - MUST specify `invreq_amount`.`msat` as greater or equal to amount expected by `offer_amount` (and, if present, `offer_currency` and `invreq_quantity`). |
| 2183 | */ |
| 2184 | /* We can't work out the expected amount without a conversion rate, so we |
| 2185 | * refuse currency offers here. We also require the exact offer amount, |
| 2186 | * which is stricter than the "greater or equal" the spec allows. */ |
| 2187 | /* We will only one-shot if we know amount! (FIXME: Convert!) */ |
| 2188 | if (b12offer->offer_currency) |
| 2189 | return command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
| 2190 | "Cannot pay offer in different currency %.*s", |
| 2191 | (int)tal_bytelen(b12offer->offer_currency), |
| 2192 | b12offer->offer_currency); |
| 2193 | if (b12offer->offer_amount) { |
| 2194 | if (msat && !amount_msat_eq(amount_msat(*b12offer->offer_amount), *msat)) { |
| 2195 | return command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
| 2196 | "Offer amount is %s, you tried to pay %s", |
| 2197 | fmt_amount_msat(tmpctx, amount_msat(*b12offer->offer_amount)), |
| 2198 | fmt_amount_msat(tmpctx, *msat)); |
| 2199 | } |
| 2200 | } else { |
| 2201 | if (!msat) |
| 2202 | return command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
| 2203 | "Must specify amount for this offer"); |
| 2204 | } |
| 2205 | if (offer_recurrence(b12offer)) |
| 2206 | return command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
| 2207 | "Cannot xpay recurring offers"); |
| 2208 | |
| 2209 | if (msat) |
| 2210 | *authorized = *msat; |
| 2211 | else |
| 2212 | *authorized = amount_msat(*b12offer->offer_amount); |
| 2213 | |
| 2214 | return NULL; |
| 2215 | } |
| 2216 | |
| 2217 | static struct command_result * |
| 2218 | check_offer_sendamount_payable(struct command *cmd, const char *offerstr) |
no test coverage detected