2019-04-14 16:55:40 +00:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
cfg = config.services.recurring-donations;
|
2021-02-03 21:44:41 +00:00
|
|
|
nbLib = config.nix-bitcoin.lib;
|
2019-04-14 16:55:40 +00:00
|
|
|
recurring-donations-script = pkgs.writeScript "recurring-donations.sh" ''
|
2020-11-09 21:09:09 +00:00
|
|
|
LNCLI="${config.nix-bitcoin.pkgs.clightning}/bin/lightning-cli --lightning-dir=${config.services.clightning.dataDir}"
|
2019-04-14 16:55:40 +00:00
|
|
|
pay_tallycoin() {
|
|
|
|
NAME=$1
|
|
|
|
AMOUNT=$2
|
2021-08-15 09:28:36 +00:00
|
|
|
echo "Attempting to pay $AMOUNT sat to $NAME"
|
2021-08-04 22:49:00 +00:00
|
|
|
INVOICE=$(curl --socks5-hostname ${config.nix-bitcoin.torClientAddressWithPort} -d "satoshi_amount=$AMOUNT&payment_method=ln&id=$NAME&type=profile" -X POST https://api.tallyco.in/v1/payment/request/ | jq -r '.lightning_pay_request') 2> /dev/null
|
2019-04-14 16:55:40 +00:00
|
|
|
if [ -z "$INVOICE" ] || [ "$INVOICE" = "null" ]; then
|
|
|
|
echo "ERROR: did not get invoice from tallycoin"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
# Decode invoice and compare amount with requested amount
|
2019-04-22 00:37:45 +00:00
|
|
|
DECODED_AMOUNT=$($LNCLI decodepay "$INVOICE" | jq -r '.amount_msat' | head -c -8)
|
2019-04-14 16:55:40 +00:00
|
|
|
if [ -z "$DECODED_AMOUNT" ] || [ "$DECODED_AMOUNT" = "null" ]; then
|
|
|
|
echo "ERROR: did not get response from clightning"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
if [ $DECODED_AMOUNT -eq $AMOUNT ]; then
|
2021-08-15 09:28:36 +00:00
|
|
|
echo "Paying with invoice $INVOICE"
|
2019-04-14 16:55:40 +00:00
|
|
|
$LNCLI pay "$INVOICE"
|
|
|
|
else
|
2021-08-15 09:28:36 +00:00
|
|
|
echo "ERROR: requested amount and invoice amount do not match. $AMOUNT vs $DECODED_AMOUNT"
|
2019-04-14 16:55:40 +00:00
|
|
|
return
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
${ builtins.foldl'
|
|
|
|
(x: receiver: x +
|
|
|
|
''
|
|
|
|
pay_tallycoin ${receiver} ${toString (builtins.getAttr receiver cfg.tallycoin)}
|
|
|
|
'')
|
|
|
|
""
|
|
|
|
(builtins.attrNames cfg.tallycoin)
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
in {
|
|
|
|
options.services.recurring-donations = {
|
2021-02-01 21:53:15 +00:00
|
|
|
enable = mkEnableOption "recurring-donations";
|
2019-04-14 16:55:40 +00:00
|
|
|
tallycoin = mkOption {
|
|
|
|
type = types.attrs;
|
|
|
|
default = {};
|
|
|
|
description = ''
|
|
|
|
This option is used to specify tallycoin donation receivers using an
|
|
|
|
attribute set. For example the following setting instructs the module
|
|
|
|
to repeatedly send 1000 satoshis to djbooth007.
|
|
|
|
{
|
|
|
|
"djbooth007" = 1000;
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
interval = mkOption {
|
2019-10-15 07:37:32 +00:00
|
|
|
type = types.str;
|
2019-04-14 16:55:40 +00:00
|
|
|
default = "Mon *-*-* 00:00:00";
|
|
|
|
description = ''
|
|
|
|
Schedules the donations. Default is weekly on Mon 00:00:00. See `man
|
|
|
|
systemd.time` for further options.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
randomizedDelaySec = mkOption {
|
|
|
|
type = types.int;
|
|
|
|
default = 86400;
|
|
|
|
description = ''
|
|
|
|
Random delay to add to scheduled time for donation. Default is one day.
|
|
|
|
'';
|
|
|
|
};
|
2021-02-03 21:44:41 +00:00
|
|
|
enforceTor = nbLib.enforceTor;
|
2019-04-14 16:55:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
2020-10-18 12:49:20 +00:00
|
|
|
services.clightning.enable = true;
|
2020-06-15 10:34:11 +00:00
|
|
|
|
2019-04-14 16:55:40 +00:00
|
|
|
systemd.services.recurring-donations = {
|
|
|
|
requires = [ "clightning.service" ];
|
|
|
|
after = [ "clightning.service" ];
|
2021-01-30 22:08:43 +00:00
|
|
|
path = with pkgs; [ nix-bitcoin.clightning curl jq ];
|
2021-02-03 21:44:41 +00:00
|
|
|
serviceConfig = nbLib.defaultHardening // {
|
2019-04-14 16:55:40 +00:00
|
|
|
ExecStart = "${pkgs.bash}/bin/bash ${recurring-donations-script}";
|
2020-05-03 15:31:50 +00:00
|
|
|
User = "recurring-donations";
|
2019-04-14 16:55:40 +00:00
|
|
|
Type = "oneshot";
|
2021-03-22 12:19:45 +00:00
|
|
|
} // nbLib.allowedIPAddresses cfg.enforceTor;
|
2019-04-14 16:55:40 +00:00
|
|
|
};
|
|
|
|
systemd.timers.recurring-donations = {
|
|
|
|
requires = [ "clightning.service" ];
|
|
|
|
after = [ "clightning.service" ];
|
|
|
|
timerConfig = {
|
|
|
|
Unit = "recurring-donations.service";
|
|
|
|
OnCalendar = cfg.interval;
|
|
|
|
RandomizedDelaySec = toString cfg.randomizedDelaySec;
|
|
|
|
};
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
};
|
2021-02-01 21:53:22 +00:00
|
|
|
|
|
|
|
users.users.recurring-donations = {
|
2021-08-04 22:48:59 +00:00
|
|
|
isSystemUser = true;
|
2021-02-01 21:53:22 +00:00
|
|
|
group = "recurring-donations";
|
2021-02-16 16:52:45 +00:00
|
|
|
extraGroups = [ config.services.clightning.group ];
|
2021-02-01 21:53:22 +00:00
|
|
|
};
|
|
|
|
users.groups.recurring-donations = {};
|
2019-04-14 16:55:40 +00:00
|
|
|
};
|
|
|
|
}
|