diff --git a/plugins/offers_offer.c b/plugins/offers_offer.c index 080968bcf..9d270ec5a 100644 --- a/plugins/offers_offer.c +++ b/plugins/offers_offer.c @@ -319,6 +319,28 @@ struct command_result *json_offer(struct command *cmd, NULL)) return command_param_failed(); + /* BOLT-offers #12: + * - MUST NOT set `quantity_min` or `quantity_max` less than 1. + */ + if (offer->quantity_min && *offer->quantity_min < 1) + return command_fail_badparam(cmd, "quantity_min", + buffer, params, + "must be >= 1"); + if (offer->quantity_max && *offer->quantity_max < 1) + return command_fail_badparam(cmd, "quantity_max", + buffer, params, + "must be >= 1"); + /* BOLT-offers #12: + * - if both: + * - MUST set `quantity_min` less than or equal to `quantity_max`. + */ + if (offer->quantity_min && offer->quantity_max) { + if (*offer->quantity_min > *offer->quantity_max) + return command_fail_badparam(cmd, "quantity_min", + buffer, params, + "must be <= quantity_max"); + } + /* BOLT-offers #12: * * - if the chain for the invoice is not solely bitcoin: diff --git a/tests/test_pay.py b/tests/test_pay.py index 49c1f7e35..8e870723b 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -4006,6 +4006,26 @@ def test_offer(node_factory, bitcoind): offer['bolt12']]).decode('UTF-8') assert 'quantity_max: 2' in output + # BOLT-offers #12: + # * - MUST NOT set `quantity_min` or `quantity_max` less than 1. + with pytest.raises(RpcError, match='quantity_min: must be >= 1'): + ret = l1.rpc.call('offer', {'amount': '100000sat', + 'description': 'quantity_min test', + 'quantity_min': 0}) + + with pytest.raises(RpcError, match='quantity_max: must be >= 1'): + ret = l1.rpc.call('offer', {'amount': '100000sat', + 'description': 'quantity_max test', + 'quantity_max': 0}) + # BOLT-offers #12: + # - if both: + # - MUST set `quantity_min` greater or equal to `quantity_max`. + with pytest.raises(RpcError, match='quantity_min: must be <= quantity_max'): + ret = l1.rpc.call('offer', {'amount': '100000sat', + 'description': 'quantity_max test', + 'quantity_min': 10, + 'quantity_max': 9}) + # Test absolute_expiry exp = int(time.time() + 2) ret = l1.rpc.call('offer', {'amount': '100000sat',