Merge #164: Add JoinMarket Clientserver
dd882753e6
joinmarket: add usage documentation (nixbitcoin)d0701f518c
joinmarket: automatically generate wallet (nixbitcoin)d6d3e8ff62
joinmarket: add tests (nixbitcoin)cce27da2ec
backups: add joinmarket datadir to includelist (nixbitcoin)173891fa5b
joinmarket: add module (nixbitcoin)263525d724
nix-bitcoin-services: add nb-services.privileged helper (nixbitcoin)f00d1d24c5
joinmarket: add pkg and local dependencies (nixbitcoin) Pull request description: ACKs for top commit: jonasnick: ACKdd882753e6
Tree-SHA512: ad7bf56314877045bc8dc6037f966535dc3607d9e941cd03d19b610ee789307eac07447df7f93569dfa3e7553e8fc6d9757bdf8542fb123c5a2e2adec8f907a2
This commit is contained in:
commit
4cf31f8612
@ -34,6 +34,8 @@ env:
|
|||||||
- PKG=liquid-swap STABLE=1
|
- PKG=liquid-swap STABLE=1
|
||||||
- PKG=lightning-loop STABLE=0
|
- PKG=lightning-loop STABLE=0
|
||||||
- PKG=nixops19_09 STABLE=1
|
- PKG=nixops19_09 STABLE=1
|
||||||
|
- PKG=joinmarket STABLE=1
|
||||||
|
- PKG=joinmarket STABLE=0
|
||||||
script:
|
script:
|
||||||
- printf '%s (%s)\n' "$NIX_PATH" "$VER"
|
- printf '%s (%s)\n' "$NIX_PATH" "$VER"
|
||||||
- |
|
- |
|
||||||
|
117
docs/usage.md
117
docs/usage.md
@ -221,3 +221,120 @@ Initialize a Trezor for Bitcoin Core's Hardware Wallet Interface
|
|||||||
```
|
```
|
||||||
|
|
||||||
8. Follow Bitcoin Core's instructions on [Using Bitcoin Core with Hardware Wallets](https://github.com/bitcoin-core/HWI/blob/master/docs/bitcoin-core-usage.md) to use your Trezor with `bitcoin-cli` on your nix-bitcoin node
|
8. Follow Bitcoin Core's instructions on [Using Bitcoin Core with Hardware Wallets](https://github.com/bitcoin-core/HWI/blob/master/docs/bitcoin-core-usage.md) to use your Trezor with `bitcoin-cli` on your nix-bitcoin node
|
||||||
|
|
||||||
|
JoinMarket
|
||||||
|
---
|
||||||
|
|
||||||
|
## Diff to regular JoinMarket usage
|
||||||
|
|
||||||
|
For clarity reasons, nix-bitcoin renames all scripts to `jm-*` without `.py`, for
|
||||||
|
example `wallet-tool.py` becomes `jm-wallet-tool`. The rest of this section
|
||||||
|
details nix-bitcoin specific workflows for JoinMarket.
|
||||||
|
|
||||||
|
## Initialize JoinMarket Wallet
|
||||||
|
|
||||||
|
By default, nix-bitcoin's JoinMarket module automatically generates a wallet for
|
||||||
|
you. If however, you want to manually initialize your wallet, follow these steps.
|
||||||
|
|
||||||
|
1. Enable JoinMarket in your node configuration
|
||||||
|
|
||||||
|
```
|
||||||
|
services.joinmarket.enable = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Move the automatically generated `wallet.jmdat`
|
||||||
|
|
||||||
|
```console
|
||||||
|
rm /var/lib/joinmarket/wallet.jmdat /var/lib/joinmarket/bak.jmdat
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Generate wallet on your node
|
||||||
|
|
||||||
|
```console
|
||||||
|
jm-wallet-tool generate
|
||||||
|
```
|
||||||
|
Follow the on-screen instructions and write down your seed.
|
||||||
|
|
||||||
|
In order to use nix-bitcoin's `joinmarket.yieldgenerator`, use the password
|
||||||
|
from `/secrets/jm-wallet-password` and use the suggested default wallet name
|
||||||
|
`wallet.jmdat`. If you want to use your own `jm-wallet-password`, simply
|
||||||
|
replace the password string in your local secrets directory.
|
||||||
|
|
||||||
|
## Run the tumbler
|
||||||
|
|
||||||
|
The tumbler needs to be able to run in the background for a long time, use screen
|
||||||
|
to run it accross ssh sessions. You can also use tmux in the same fashion.
|
||||||
|
|
||||||
|
1. Add screen to your `environment.systemPackages`, for example
|
||||||
|
|
||||||
|
```
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
vim
|
||||||
|
screen
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Start the screen session
|
||||||
|
|
||||||
|
```console
|
||||||
|
screen -S "tumbler"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Start the tumbler
|
||||||
|
|
||||||
|
Example: Tumbling into your wallet after buying from an exchange to improve privacy:
|
||||||
|
|
||||||
|
```console
|
||||||
|
jm-tumbler wallet.jmdat <addr1> <addr2> <addr3>
|
||||||
|
```
|
||||||
|
|
||||||
|
After tumbling your bitcoin end up in these three addresses. You can now
|
||||||
|
spend them without the exchange collecting data on your purchases.
|
||||||
|
|
||||||
|
Get more information [here](https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/tumblerguide.md)
|
||||||
|
|
||||||
|
3. Detach the screen session to leave the tumbler running in the background
|
||||||
|
|
||||||
|
```
|
||||||
|
Ctrl-a d or Ctrl-a Ctrl-d
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Re-attach to the screen session
|
||||||
|
|
||||||
|
```console
|
||||||
|
screen -r tumbler
|
||||||
|
```
|
||||||
|
|
||||||
|
5. End screen session
|
||||||
|
|
||||||
|
Type exit when tumbler is done
|
||||||
|
|
||||||
|
```console
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run a "maker" or "yield generator"
|
||||||
|
|
||||||
|
The maker/yield generator in nix-bitcoin is implemented using a systemd service.
|
||||||
|
|
||||||
|
See [here](https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/YIELDGENERATOR.md) for more yield generator information.
|
||||||
|
|
||||||
|
1. Enable yield generator bot in your node configuration
|
||||||
|
|
||||||
|
```
|
||||||
|
services.joinmarket.yieldgenerator.enable = true;
|
||||||
|
|
||||||
|
# Optional: Add custom parameters
|
||||||
|
services.joinmarket.yieldgenerator.customParameters = ''
|
||||||
|
txfee = 200
|
||||||
|
cjfee_a = 300
|
||||||
|
'';
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Check service status
|
||||||
|
|
||||||
|
```console
|
||||||
|
systemctl status joinmarket-yieldgenerator
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Profit
|
||||||
|
@ -172,6 +172,16 @@
|
|||||||
# and electrs data directory, enable
|
# and electrs data directory, enable
|
||||||
# services.backups.with-bulk-data = true;
|
# services.backups.with-bulk-data = true;
|
||||||
|
|
||||||
|
### JOINMARKET
|
||||||
|
# Enable this module to allow using JoinMarket's user interactive scripts (including
|
||||||
|
# tumbler.py).
|
||||||
|
# Note: JoinMarket has full access to bitcoind, including its wallet functionality.
|
||||||
|
# services.joinmarket.enable = true;
|
||||||
|
# Enable this option to enable the JoinMarket Yield Generator Bot. You will be able to
|
||||||
|
# earn sats by providing CoinJoin liquidity. This makes it impossible to use other
|
||||||
|
# scripts that access your wallet.
|
||||||
|
# services.joinmarket.yieldgenerator.enable = true;
|
||||||
|
|
||||||
# FIXME: Define your hostname.
|
# FIXME: Define your hostname.
|
||||||
networking.hostName = "nix-bitcoin";
|
networking.hostName = "nix-bitcoin";
|
||||||
time.timeZone = "UTC";
|
time.timeZone = "UTC";
|
||||||
|
@ -18,6 +18,8 @@ let
|
|||||||
${config.services.lightning-charge.dataDir}
|
${config.services.lightning-charge.dataDir}
|
||||||
${config.services.nbxplorer.dataDir}
|
${config.services.nbxplorer.dataDir}
|
||||||
${config.services.btcpayserver.dataDir}
|
${config.services.btcpayserver.dataDir}
|
||||||
|
${config.services.joinmarket.dataDir}
|
||||||
|
/secrets/jm-wallet-seed
|
||||||
/var/lib/tor
|
/var/lib/tor
|
||||||
# Extra files
|
# Extra files
|
||||||
${cfg.extraFiles}
|
${cfg.extraFiles}
|
||||||
|
@ -12,4 +12,5 @@
|
|||||||
spark-wallet = ./spark-wallet.nix;
|
spark-wallet = ./spark-wallet.nix;
|
||||||
recurring-donations = ./recurring-donations.nix;
|
recurring-donations = ./recurring-donations.nix;
|
||||||
lnd = ./lnd.nix;
|
lnd = ./lnd.nix;
|
||||||
|
joinmarket = ./joinmarket.nix;
|
||||||
}
|
}
|
||||||
|
219
modules/joinmarket.nix
Normal file
219
modules/joinmarket.nix
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.joinmarket;
|
||||||
|
inherit (config) nix-bitcoin-services;
|
||||||
|
secretsDir = config.nix-bitcoin.secretsDir;
|
||||||
|
|
||||||
|
torAddress = builtins.head (builtins.split ":" config.services.tor.client.socksListenAddress);
|
||||||
|
configFile = builtins.toFile "config" ''
|
||||||
|
# Based on https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/jmclient/jmclient/configure.py
|
||||||
|
[DAEMON]
|
||||||
|
no_daemon = 0
|
||||||
|
daemon_port = 27183
|
||||||
|
daemon_host = localhost
|
||||||
|
use_ssl = false
|
||||||
|
|
||||||
|
[BLOCKCHAIN]
|
||||||
|
blockchain_source = bitcoin-rpc
|
||||||
|
network = mainnet
|
||||||
|
rpc_host = ${builtins.elemAt config.services.bitcoind.rpcbind 0}
|
||||||
|
rpc_port = 8332
|
||||||
|
rpc_user = ${config.services.bitcoind.rpc.users.privileged.name}
|
||||||
|
@@RPC_PASSWORD@@
|
||||||
|
|
||||||
|
[MESSAGING:server1]
|
||||||
|
host = darksci3bfoka7tw.onion
|
||||||
|
channel = joinmarket-pit
|
||||||
|
port = 6697
|
||||||
|
usessl = true
|
||||||
|
socks5 = true
|
||||||
|
socks5_host = ${torAddress}
|
||||||
|
socks5_port = 9050
|
||||||
|
|
||||||
|
[MESSAGING:server2]
|
||||||
|
host = ncwkrwxpq2ikcngxq3dy2xctuheniggtqeibvgofixpzvrwpa77tozqd.onion
|
||||||
|
channel = joinmarket-pit
|
||||||
|
port = 6667
|
||||||
|
usessl = false
|
||||||
|
socks5 = true
|
||||||
|
socks5_host = ${torAddress}
|
||||||
|
socks5_port = 9050
|
||||||
|
|
||||||
|
[LOGGING]
|
||||||
|
console_log_level = INFO
|
||||||
|
color = false
|
||||||
|
|
||||||
|
[POLICY]
|
||||||
|
segwit = true
|
||||||
|
native = false
|
||||||
|
merge_algorithm = default
|
||||||
|
tx_fees = 3
|
||||||
|
absurd_fee_per_kb = 350000
|
||||||
|
tx_broadcast = self
|
||||||
|
minimum_makers = 4
|
||||||
|
max_sats_freeze_reuse = -1
|
||||||
|
taker_utxo_retries = 3
|
||||||
|
taker_utxo_age = 5
|
||||||
|
taker_utxo_amtpercent = 20
|
||||||
|
accept_commitment_broadcasts = 1
|
||||||
|
commit_file_location = cmtdata/commitments.json
|
||||||
|
'';
|
||||||
|
|
||||||
|
# The jm scripts create a 'logs' dir in the working dir,
|
||||||
|
# so run them inside dataDir.
|
||||||
|
cli = pkgs.runCommand "joinmarket-cli" {} ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
jm=${pkgs.nix-bitcoin.joinmarket}/bin
|
||||||
|
cd $jm
|
||||||
|
for bin in jm-*; do
|
||||||
|
{
|
||||||
|
echo "#!${pkgs.bash}/bin/bash";
|
||||||
|
echo "cd '${cfg.dataDir}' && ${cfg.cliExec} sudo -u ${cfg.user} $jm/$bin --datadir='${cfg.dataDir}' \"\$@\"";
|
||||||
|
} > $out/bin/$bin
|
||||||
|
done
|
||||||
|
chmod -R +x $out/bin
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
options.services.joinmarket = {
|
||||||
|
enable = mkEnableOption "JoinMarket";
|
||||||
|
yieldgenerator = {
|
||||||
|
enable = mkEnableOption "yield generator bot";
|
||||||
|
customParameters = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
example = ''
|
||||||
|
txfee = 200
|
||||||
|
cjfee_a = 300
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Python code to define custom yield generator parameters, as described in
|
||||||
|
https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/YIELDGENERATOR.md
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/joinmarket";
|
||||||
|
description = "The data directory for JoinMarket.";
|
||||||
|
};
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "joinmarket";
|
||||||
|
description = "The user as which to run JoinMarket.";
|
||||||
|
};
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = cfg.user;
|
||||||
|
description = "The group as which to run JoinMarket.";
|
||||||
|
};
|
||||||
|
cli = mkOption {
|
||||||
|
default = cli;
|
||||||
|
};
|
||||||
|
inherit (nix-bitcoin-services) cliExec;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable (mkMerge [{
|
||||||
|
environment.systemPackages = [
|
||||||
|
(hiPrio cfg.cli)
|
||||||
|
];
|
||||||
|
users.users.${cfg.user} = {
|
||||||
|
description = "joinmarket User";
|
||||||
|
group = "${cfg.group}";
|
||||||
|
home = cfg.dataDir;
|
||||||
|
};
|
||||||
|
users.groups.${cfg.group} = {};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.bitcoind.disablewallet = false;
|
||||||
|
|
||||||
|
# Joinmarket is TOR-only
|
||||||
|
services.tor = {
|
||||||
|
enable = true;
|
||||||
|
client.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.joinmarket = {
|
||||||
|
description = "JoinMarket Daemon";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
requires = [ "bitcoind.service" ];
|
||||||
|
after = [ "bitcoind.service" ];
|
||||||
|
path = [ pkgs.sudo ];
|
||||||
|
serviceConfig = nix-bitcoin-services.defaultHardening // {
|
||||||
|
ExecStartPre = nix-bitcoin-services.privileged ''
|
||||||
|
install -o '${cfg.user}' -g '${cfg.group}' -m 640 ${configFile} ${cfg.dataDir}/joinmarket.cfg
|
||||||
|
sed -i \
|
||||||
|
"s|@@RPC_PASSWORD@@|rpc_password = $(cat ${secretsDir}/bitcoin-rpcpassword-privileged)|" \
|
||||||
|
'${cfg.dataDir}/joinmarket.cfg'
|
||||||
|
'';
|
||||||
|
ExecStartPost = nix-bitcoin-services.privileged ''
|
||||||
|
walletname=wallet.jmdat
|
||||||
|
pw=$(cat "${secretsDir}"/jm-wallet-password)
|
||||||
|
mnemonic=${secretsDir}/jm-wallet-seed
|
||||||
|
if [[ ! -f ${cfg.dataDir}/wallets/$walletname ]]; then
|
||||||
|
echo Create joinmarket wallet
|
||||||
|
# Use bash variables so commands don't proceed on previous failures
|
||||||
|
# (like with pipes)
|
||||||
|
cd ${cfg.dataDir} && \
|
||||||
|
out=$(sudo -u ${cfg.user} \
|
||||||
|
${pkgs.nix-bitcoin.joinmarket}/bin/jm-genwallet \
|
||||||
|
--datadir=${cfg.dataDir} $walletname $pw)
|
||||||
|
recoveryseed=$(echo "$out" | grep 'recovery_seed')
|
||||||
|
echo "$recoveryseed" | cut -d ':' -f2 > $mnemonic
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
ExecStart = "${pkgs.nix-bitcoin.joinmarket}/bin/joinmarketd";
|
||||||
|
WorkingDirectory = "${cfg.dataDir}"; # The service creates 'commitmentlist' in the working dir
|
||||||
|
User = "${cfg.user}";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = "10s";
|
||||||
|
ReadWritePaths = "${cfg.dataDir}";
|
||||||
|
} // nix-bitcoin-services.allowTor;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
(mkIf cfg.yieldgenerator.enable {
|
||||||
|
nix-bitcoin.secrets.jm-wallet-password.user = cfg.user;
|
||||||
|
|
||||||
|
systemd.services.joinmarket-yieldgenerator = let
|
||||||
|
ygDefault = "${pkgs.nix-bitcoin.joinmarket}/bin/jm-yg-privacyenhanced";
|
||||||
|
ygBinary = if cfg.yieldgenerator.customParameters == "" then
|
||||||
|
ygDefault
|
||||||
|
else
|
||||||
|
pkgs.runCommand "jm-yieldgenerator-custom" {
|
||||||
|
inherit (cfg.yieldgenerator) customParameters;
|
||||||
|
} ''
|
||||||
|
substitute ${ygDefault} $out \
|
||||||
|
--replace "# end of settings customization" "$customParameters"
|
||||||
|
chmod +x $out
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
description = "CoinJoin maker bot to gain privacy and passively generate income";
|
||||||
|
wantedBy = [ "joinmarket.service" ];
|
||||||
|
requires = [ "joinmarket.service" ];
|
||||||
|
after = [ "joinmarket.service" ];
|
||||||
|
preStart = let
|
||||||
|
start = ''
|
||||||
|
exec ${ygBinary} --datadir='${cfg.dataDir}' --wallet-password-stdin wallet.jmdat
|
||||||
|
'';
|
||||||
|
in ''
|
||||||
|
pw=$(cat "${secretsDir}"/jm-wallet-password)
|
||||||
|
echo "echo -n $pw | ${start}" > $RUNTIME_DIRECTORY/start
|
||||||
|
'';
|
||||||
|
serviceConfig = nix-bitcoin-services.defaultHardening // rec {
|
||||||
|
RuntimeDirectory = "joinmarket-yieldgenerator"; # Only used to create start script
|
||||||
|
RuntimeDirectoryMode = "700";
|
||||||
|
WorkingDirectory = "${cfg.dataDir}"; # The service creates dir 'logs' in the working dir
|
||||||
|
ExecStart = "${pkgs.bash}/bin/bash /run/${RuntimeDirectory}/start";
|
||||||
|
User = "${cfg.user}";
|
||||||
|
ReadWritePaths = "${cfg.dataDir}";
|
||||||
|
} // nix-bitcoin-services.allowTor;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}
|
@ -19,6 +19,7 @@
|
|||||||
./security.nix
|
./security.nix
|
||||||
./backups.nix
|
./backups.nix
|
||||||
./btcpayserver.nix
|
./btcpayserver.nix
|
||||||
|
./joinmarket.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
disabledModules = [ "services/networking/bitcoind.nix" ];
|
disabledModules = [ "services/networking/bitcoind.nix" ];
|
||||||
|
@ -131,6 +131,7 @@ in {
|
|||||||
${ip} link del nb-br
|
${ip} link del nb-br
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
} //
|
} //
|
||||||
(let
|
(let
|
||||||
makeNetnsServices = n: v: let
|
makeNetnsServices = n: v: let
|
||||||
@ -242,6 +243,10 @@ in {
|
|||||||
++ optional (config.services.btcpayserver.lightningBackend == "lnd") "lnd";
|
++ optional (config.services.btcpayserver.lightningBackend == "lnd") "lnd";
|
||||||
# communicates with clightning over rpc socket
|
# communicates with clightning over rpc socket
|
||||||
};
|
};
|
||||||
|
joinmarket = {
|
||||||
|
id = 25;
|
||||||
|
connections = [ "bitcoind" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.bitcoind = {
|
services.bitcoind = {
|
||||||
@ -314,6 +319,9 @@ in {
|
|||||||
|
|
||||||
services.nbxplorer.bind = netns.nbxplorer.address;
|
services.nbxplorer.bind = netns.nbxplorer.address;
|
||||||
services.btcpayserver.bind = netns.btcpayserver.address;
|
services.btcpayserver.bind = netns.btcpayserver.address;
|
||||||
|
|
||||||
|
services.joinmarket.cliExec = mkCliExec "joinmarket";
|
||||||
|
systemd.services.joinmarket-yieldgenerator.serviceConfig.NetworkNamespacePath = "/var/run/netns/nb-joinmarket";
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
lib: pkgs:
|
lib: pkgs:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
{
|
let self = {
|
||||||
# These settings roughly follow systemd's "strict" security profile
|
# These settings roughly follow systemd's "strict" security profile
|
||||||
defaultHardening = {
|
defaultHardening = {
|
||||||
PrivateTmp = "true";
|
PrivateTmp = "true";
|
||||||
@ -56,10 +56,13 @@ with lib;
|
|||||||
${src}
|
${src}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# Used for ExecStart*
|
||||||
|
privileged = src: "+${self.script src}";
|
||||||
|
|
||||||
cliExec = mkOption {
|
cliExec = mkOption {
|
||||||
# Used by netns-isolation to execute the cli in the service's private netns
|
# Used by netns-isolation to execute the cli in the service's private netns
|
||||||
internal = true;
|
internal = true;
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "exec";
|
default = "exec";
|
||||||
};
|
};
|
||||||
}
|
}; in self
|
||||||
|
@ -171,7 +171,8 @@ in {
|
|||||||
++ (optionals cfg.lnd.enable [ "lnd" ])
|
++ (optionals cfg.lnd.enable [ "lnd" ])
|
||||||
++ (optionals cfg.liquidd.enable [ cfg.liquidd.group ])
|
++ (optionals cfg.liquidd.enable [ cfg.liquidd.group ])
|
||||||
++ (optionals (cfg.hardware-wallets.ledger || cfg.hardware-wallets.trezor)
|
++ (optionals (cfg.hardware-wallets.ledger || cfg.hardware-wallets.trezor)
|
||||||
[ cfg.hardware-wallets.group ]);
|
[ cfg.hardware-wallets.group ])
|
||||||
|
++ (optionals cfg.joinmarket.enable [ cfg.joinmarket.group ]);
|
||||||
openssh.authorizedKeys.keys = config.users.users.root.openssh.authorizedKeys.keys;
|
openssh.authorizedKeys.keys = config.users.users.root.openssh.authorizedKeys.keys;
|
||||||
};
|
};
|
||||||
nix-bitcoin.netns-isolation.allowedUser = operatorName;
|
nix-bitcoin.netns-isolation.allowedUser = operatorName;
|
||||||
@ -182,6 +183,9 @@ in {
|
|||||||
security.sudo.configFile =
|
security.sudo.configFile =
|
||||||
(optionalString cfg.lnd.enable ''
|
(optionalString cfg.lnd.enable ''
|
||||||
${operatorName} ALL=(lnd) NOPASSWD: ALL
|
${operatorName} ALL=(lnd) NOPASSWD: ALL
|
||||||
|
'') +
|
||||||
|
(optionalString cfg.joinmarket.enable ''
|
||||||
|
${operatorName} ALL=(${cfg.joinmarket.user}) NOPASSWD: ALL
|
||||||
'');
|
'');
|
||||||
|
|
||||||
# Enable nixops ssh for operator (`nixops ssh operator@mynode`) on nixops-vbox deployments
|
# Enable nixops ssh for operator (`nixops ssh operator@mynode`) on nixops-vbox deployments
|
||||||
|
@ -8,6 +8,7 @@ let self = {
|
|||||||
hwi = pkgs.callPackage ./hwi { };
|
hwi = pkgs.callPackage ./hwi { };
|
||||||
pylightning = pkgs.python3Packages.callPackage ./pylightning { };
|
pylightning = pkgs.python3Packages.callPackage ./pylightning { };
|
||||||
liquid-swap = pkgs.python3Packages.callPackage ./liquid-swap { };
|
liquid-swap = pkgs.python3Packages.callPackage ./liquid-swap { };
|
||||||
|
joinmarket = pkgs.callPackage ./joinmarket { };
|
||||||
generate-secrets = pkgs.callPackage ./generate-secrets { };
|
generate-secrets = pkgs.callPackage ./generate-secrets { };
|
||||||
nixops19_09 = pkgs.callPackage ./nixops { };
|
nixops19_09 = pkgs.callPackage ./nixops { };
|
||||||
netns-exec = pkgs.callPackage ./netns-exec { };
|
netns-exec = pkgs.callPackage ./netns-exec { };
|
||||||
|
@ -18,6 +18,7 @@ makePasswordSecret liquid-rpcpassword
|
|||||||
makePasswordSecret lightning-charge-token
|
makePasswordSecret lightning-charge-token
|
||||||
makePasswordSecret spark-wallet-password
|
makePasswordSecret spark-wallet-password
|
||||||
makePasswordSecret backup-encryption-password
|
makePasswordSecret backup-encryption-password
|
||||||
|
makePasswordSecret jm-wallet-password
|
||||||
|
|
||||||
[[ -e bitcoin-HMAC-privileged ]] || makeHMAC privileged
|
[[ -e bitcoin-HMAC-privileged ]] || makeHMAC privileged
|
||||||
[[ -e bitcoin-HMAC-public ]] || makeHMAC public
|
[[ -e bitcoin-HMAC-public ]] || makeHMAC public
|
||||||
|
22
pkgs/joinmarket/bencoderpyx/default.nix
Normal file
22
pkgs/joinmarket/bencoderpyx/default.nix
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{ lib, buildPythonPackage, fetchurl, cython, pytest, coverage }:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "bencoder.pyx";
|
||||||
|
version = "2.0.1";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/whtsky/bencoder.pyx/archive/v${version}.tar.gz";
|
||||||
|
sha256 = "f3ff92ac706a7e4692bed5e6cbe205963327f3076f55e408eb948659923eac72";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = [ cython ];
|
||||||
|
|
||||||
|
checkInputs = [ pytest coverage ];
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "A fast bencode implementation in Cython";
|
||||||
|
homepage = "https://github.com/whtsky/bencoder.pyx";
|
||||||
|
maintainers = with maintainers; [ nixbitcoin ];
|
||||||
|
license = licenses.bsd3;
|
||||||
|
};
|
||||||
|
}
|
24
pkgs/joinmarket/chromalog/default.nix
Normal file
24
pkgs/joinmarket/chromalog/default.nix
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{ lib, buildPythonPackage, fetchFromGitHub, colorama, future, six }:
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "chromalog";
|
||||||
|
version = "1.0.5";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "freelan-developers";
|
||||||
|
repo = "chromalog";
|
||||||
|
rev = "${version}";
|
||||||
|
sha256 = "0pj4s52rgwlvwkzrj85y92c5r9c84pz8gga45jl5spysrv41y9p0";
|
||||||
|
};
|
||||||
|
|
||||||
|
propagatedBuildInputs = [ colorama future six ];
|
||||||
|
|
||||||
|
# enable when https://github.com/freelan-developers/chromalog/issues/6 is resolved
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Enhance Python with colored logging";
|
||||||
|
homepage = "https://github.com/freelan-developers/chromalog";
|
||||||
|
maintainers = with maintainers; [ nixbitcoin ];
|
||||||
|
license = licenses.mit;
|
||||||
|
};
|
||||||
|
}
|
25
pkgs/joinmarket/coincurve/default.nix
Normal file
25
pkgs/joinmarket/coincurve/default.nix
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{ lib, buildPythonPackage, fetchPypi, asn1crypto, cffi, pkg-config, libtool, libffi, requests, gmp }:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "coincurve";
|
||||||
|
version = "13.0.0";
|
||||||
|
|
||||||
|
src = fetchPypi {
|
||||||
|
inherit pname version;
|
||||||
|
sha256 = "1x8dpbq6bwswfyi1g4r421hnswp904l435rf7n6fj7y8q1yn51cr";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = [ pkg-config libtool libffi gmp ];
|
||||||
|
|
||||||
|
propagatedBuildInputs = [ asn1crypto cffi requests ];
|
||||||
|
|
||||||
|
# enable when https://github.com/ofek/coincurve/issues/47 is resolved
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Cross-platform Python CFFI bindings for libsecp256k1";
|
||||||
|
homepage = "https://github.com/ofek/coincurve";
|
||||||
|
maintainers = with maintainers; [ nixbitcoin ];
|
||||||
|
license = licenses.asl20;
|
||||||
|
};
|
||||||
|
}
|
71
pkgs/joinmarket/default.nix
Normal file
71
pkgs/joinmarket/default.nix
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
{ stdenv, fetchurl, python3, pkgs }:
|
||||||
|
|
||||||
|
let
|
||||||
|
version = "0.7.0";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/JoinMarket-Org/joinmarket-clientserver/archive/v${version}.tar.gz";
|
||||||
|
sha256 = "0ha73n3y5lykyj3pl97a619sxd2zz0lb32s5c61wm0l1h47v9l1g";
|
||||||
|
};
|
||||||
|
|
||||||
|
python = python3.override {
|
||||||
|
packageOverrides = self: super: let
|
||||||
|
joinmarketPkg = pkg: self.callPackage pkg { inherit version src; };
|
||||||
|
in {
|
||||||
|
joinmarketbase = joinmarketPkg ./jmbase;
|
||||||
|
joinmarketclient = joinmarketPkg ./jmclient;
|
||||||
|
joinmarketbitcoin = joinmarketPkg ./jmbitcoin;
|
||||||
|
joinmarketdaemon = joinmarketPkg ./jmdaemon;
|
||||||
|
|
||||||
|
chromalog = self.callPackage ./chromalog {};
|
||||||
|
bencoderpyx = self.callPackage ./bencoderpyx {};
|
||||||
|
coincurve = self.callPackage ./coincurve {};
|
||||||
|
urldecode = self.callPackage ./urldecode {};
|
||||||
|
python-bitcointx = self.callPackage ./python-bitcointx {};
|
||||||
|
secp256k1 = self.callPackage ./secp256k1 {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
runtimePackages = with python.pkgs; [
|
||||||
|
joinmarketbase
|
||||||
|
joinmarketclient
|
||||||
|
joinmarketbitcoin
|
||||||
|
joinmarketdaemon
|
||||||
|
];
|
||||||
|
|
||||||
|
genwallet = pkgs.writeScriptBin "genwallet" (builtins.readFile ./genwallet/genwallet.py);
|
||||||
|
|
||||||
|
pythonEnv = python.withPackages (_: runtimePackages);
|
||||||
|
in
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "joinmarket";
|
||||||
|
inherit version src genwallet;
|
||||||
|
|
||||||
|
buildInputs = [ pythonEnv ];
|
||||||
|
|
||||||
|
buildCommand = ''
|
||||||
|
mkdir -p $src-unpacked $out/bin
|
||||||
|
tar xzf $src --strip 1 -C $src-unpacked
|
||||||
|
|
||||||
|
# add-utxo.py -> bin/jm-add-utxo
|
||||||
|
cpBin() {
|
||||||
|
cp $src-unpacked/scripts/$1 $out/bin/jm-''${1%.py}
|
||||||
|
}
|
||||||
|
cp $src-unpacked/scripts/joinmarketd.py $out/bin/joinmarketd
|
||||||
|
cpBin add-utxo.py
|
||||||
|
cpBin convert_old_wallet.py
|
||||||
|
cpBin receive-payjoin.py
|
||||||
|
cpBin sendpayment.py
|
||||||
|
cpBin sendtomany.py
|
||||||
|
cpBin tumbler.py
|
||||||
|
cpBin wallet-tool.py
|
||||||
|
cpBin yg-privacyenhanced.py
|
||||||
|
cp $genwallet/bin/genwallet $out/bin/jm-genwallet
|
||||||
|
|
||||||
|
chmod +x -R $out/bin
|
||||||
|
patchShebangs $out/bin
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
inherit python runtimePackages pythonEnv;
|
||||||
|
};
|
||||||
|
}
|
36
pkgs/joinmarket/genwallet/genwallet.py
Normal file
36
pkgs/joinmarket/genwallet/genwallet.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
"""
|
||||||
|
Prototype: demonstrate you can automatically generate a wallet
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from optparse import OptionParser
|
||||||
|
from jmclient import load_program_config, add_base_options, SegwitLegacyWallet, create_wallet, jm_single
|
||||||
|
from jmbase.support import get_log, jmprint
|
||||||
|
|
||||||
|
log = get_log()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = OptionParser(
|
||||||
|
usage='usage: %prog [options] wallet_file_name password',
|
||||||
|
description='Create a wallet with the given wallet name and password.')
|
||||||
|
add_base_options(parser)
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
if options.wallet_password_stdin:
|
||||||
|
stdin = sys.stdin.read()
|
||||||
|
password = stdin.encode("utf-8")
|
||||||
|
else:
|
||||||
|
assert len(args) > 1, "must provide password via stdin (see --help), or as second argument."
|
||||||
|
password = args[1].encode("utf-8")
|
||||||
|
load_program_config(config_path=options.datadir)
|
||||||
|
wallet_root_path = os.path.join(jm_single().datadir, "wallets")
|
||||||
|
wallet_name = os.path.join(wallet_root_path, args[0])
|
||||||
|
wallet = create_wallet(wallet_name, password, 4, SegwitLegacyWallet)
|
||||||
|
jmprint("recovery_seed:{}"
|
||||||
|
.format(wallet.get_mnemonic_words()[0]), "important")
|
||||||
|
wallet.close()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
25
pkgs/joinmarket/get-sha256.sh
Executable file
25
pkgs/joinmarket/get-sha256.sh
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#! /usr/bin/env nix-shell
|
||||||
|
#! nix-shell -i bash -p git gnupg
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TMPDIR="$(mktemp -d -p /tmp)"
|
||||||
|
trap "rm -rf $TMPDIR" EXIT
|
||||||
|
cd $TMPDIR
|
||||||
|
|
||||||
|
echo "Fetching latest release"
|
||||||
|
git clone https://github.com/joinmarket-org/joinmarket-clientserver 2> /dev/null
|
||||||
|
cd joinmarket-clientserver
|
||||||
|
latest=$(git describe --tags `git rev-list --tags --max-count=1`)
|
||||||
|
echo "Latest release is ${latest}"
|
||||||
|
|
||||||
|
# GPG verification
|
||||||
|
export GNUPGHOME=$TMPDIR
|
||||||
|
echo "Fetching Adam Gibson's key"
|
||||||
|
gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 2B6FC204D9BF332D062B461A141001A1AF77F20B 2> /dev/null
|
||||||
|
echo "Verifying latest release"
|
||||||
|
git verify-tag ${latest}
|
||||||
|
|
||||||
|
echo "tag: ${latest}"
|
||||||
|
# The prefix option is necessary because GitHub prefixes the archive contents in this format
|
||||||
|
echo "sha256: $(nix-hash --type sha256 --flat --base32 \
|
||||||
|
<(git archive --format tar.gz --prefix=joinmarket-clientserver-"${latest//v}"/ ${latest}))"
|
16
pkgs/joinmarket/jmbase/default.nix
Normal file
16
pkgs/joinmarket/jmbase/default.nix
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{ version, src, lib, buildPythonPackage, fetchurl, future, twisted, service-identity, chromalog }:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "joinmarketbase";
|
||||||
|
inherit version src;
|
||||||
|
|
||||||
|
postUnpack = "sourceRoot=$sourceRoot/jmbase";
|
||||||
|
|
||||||
|
propagatedBuildInputs = [ future twisted service-identity chromalog ];
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
homepage = "https://github.com/Joinmarket-Org/joinmarket-clientserver";
|
||||||
|
maintainers = with maintainers; [ nixbitcoin ];
|
||||||
|
license = licenses.gpl3;
|
||||||
|
};
|
||||||
|
}
|
18
pkgs/joinmarket/jmbitcoin/default.nix
Normal file
18
pkgs/joinmarket/jmbitcoin/default.nix
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{ version, src, lib, buildPythonPackage, fetchurl, future, coincurve, urldecode, pyaes, python-bitcointx, secp256k1, joinmarketbase }:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "joinmarketbitcoin";
|
||||||
|
inherit version src;
|
||||||
|
|
||||||
|
postUnpack = "sourceRoot=$sourceRoot/jmbitcoin";
|
||||||
|
|
||||||
|
propagatedBuildInputs = [ future coincurve urldecode pyaes python-bitcointx secp256k1 ];
|
||||||
|
|
||||||
|
checkInputs = [ joinmarketbase ];
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
homepage = "https://github.com/Joinmarket-Org/joinmarket-clientserver";
|
||||||
|
maintainers = with maintainers; [ nixbitcoin ];
|
||||||
|
license = licenses.gpl3;
|
||||||
|
};
|
||||||
|
}
|
20
pkgs/joinmarket/jmclient/default.nix
Normal file
20
pkgs/joinmarket/jmclient/default.nix
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{ version, src, lib, buildPythonPackage, fetchurl, future, configparser, joinmarketbase, mnemonic, argon2_cffi, bencoderpyx, pyaes, joinmarketbitcoin, txtorcon }:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "joinmarketclient";
|
||||||
|
inherit version src;
|
||||||
|
|
||||||
|
postUnpack = "sourceRoot=$sourceRoot/jmclient";
|
||||||
|
|
||||||
|
checkInputs = [ joinmarketbitcoin txtorcon ];
|
||||||
|
|
||||||
|
# configparser may need to be compiled with python_version<"3.2"
|
||||||
|
propagatedBuildInputs = [ future configparser joinmarketbase mnemonic argon2_cffi bencoderpyx pyaes ];
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Client library for Bitcoin coinjoins";
|
||||||
|
homepage = "https://github.com/Joinmarket-Org/joinmarket-clientserver";
|
||||||
|
maintainers = with maintainers; [ nixbitcoin ];
|
||||||
|
license = licenses.gpl3;
|
||||||
|
};
|
||||||
|
}
|
17
pkgs/joinmarket/jmdaemon/default.nix
Normal file
17
pkgs/joinmarket/jmdaemon/default.nix
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{ version, src, lib, buildPythonPackage, fetchurl, future, txtorcon, pyopenssl, libnacl, joinmarketbase }:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "joinmarketdaemon";
|
||||||
|
inherit version src;
|
||||||
|
|
||||||
|
postUnpack = "sourceRoot=$sourceRoot/jmdaemon";
|
||||||
|
|
||||||
|
propagatedBuildInputs = [ future txtorcon pyopenssl libnacl joinmarketbase ];
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Client library for Bitcoin coinjoins";
|
||||||
|
homepage = "https://github.com/Joinmarket-Org/joinmarket-clientserver";
|
||||||
|
maintainers = with maintainers; [ nixbitcoin ];
|
||||||
|
license = licenses.gpl3;
|
||||||
|
};
|
||||||
|
}
|
27
pkgs/joinmarket/python-bitcointx/default.nix
Normal file
27
pkgs/joinmarket/python-bitcointx/default.nix
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{ lib, buildPythonPackage, fetchurl, secp256k1, openssl }:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "python-bitcointx";
|
||||||
|
version = "1.1.1";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/Simplexum/${pname}/archive/${pname}-v${version}.tar.gz";
|
||||||
|
sha256 = "35edd694473517508367338888633954eaa91b2622b3caada8fd3030ddcacba2";
|
||||||
|
};
|
||||||
|
|
||||||
|
patchPhase = ''
|
||||||
|
for path in core/secp256k1.py tests/test_load_secp256k1.py; do
|
||||||
|
substituteInPlace "bitcointx/$path" \
|
||||||
|
--replace "ctypes.util.find_library('secp256k1')" "'${secp256k1}/lib/libsecp256k1.so'"
|
||||||
|
done
|
||||||
|
substituteInPlace bitcointx/core/key.py \
|
||||||
|
--replace "ctypes.util.find_library('ssl')" "'${openssl.out}/lib/libssl.so'"
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Interface to Bitcoin transaction data structures";
|
||||||
|
homepage = "https://github.com/Simplexum/python-bitcointx";
|
||||||
|
maintainers = with maintainers; [ nixbitcoin ];
|
||||||
|
license = licenses.gpl3;
|
||||||
|
};
|
||||||
|
}
|
24
pkgs/joinmarket/python-bitcointx/get-sha256.sh
Executable file
24
pkgs/joinmarket/python-bitcointx/get-sha256.sh
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#! /usr/bin/env nix-shell
|
||||||
|
#! nix-shell -i bash -p git gnupg
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TMPDIR="$(mktemp -d -p /tmp)"
|
||||||
|
trap "rm -rf $TMPDIR" EXIT
|
||||||
|
cd $TMPDIR
|
||||||
|
|
||||||
|
echo "Fetching latest release"
|
||||||
|
git clone https://github.com/simplexum/python-bitcointx 2> /dev/null
|
||||||
|
cd python-bitcointx
|
||||||
|
latest=$(git describe --tags `git rev-list --tags --max-count=1`)
|
||||||
|
echo "Latest release is ${latest}"
|
||||||
|
|
||||||
|
# GPG verification
|
||||||
|
export GNUPGHOME=$TMPDIR
|
||||||
|
echo "Fetching Dimitry Pethukov's Key"
|
||||||
|
gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys B17A35BBA187395784E2A6B32301D26BDC15160D 2> /dev/null
|
||||||
|
echo "Verifying latest release"
|
||||||
|
git verify-commit ${latest}
|
||||||
|
|
||||||
|
echo "tag: ${latest}"
|
||||||
|
# The prefix option is necessary because GitHub prefixes the archive contents in this format
|
||||||
|
echo "sha256: $(git archive --format tar.gz --prefix=python-bitcointx-"${latest}"/ ${latest} | sha256sum | cut -d\ -f1)"
|
28
pkgs/joinmarket/secp256k1/default.nix
Normal file
28
pkgs/joinmarket/secp256k1/default.nix
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{ stdenv, fetchFromGitHub, autoreconfHook }:
|
||||||
|
|
||||||
|
let inherit (stdenv.lib) optionals; in
|
||||||
|
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "secp256k1";
|
||||||
|
|
||||||
|
version = "2019-10-11";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "bitcoin-core";
|
||||||
|
repo = "secp256k1";
|
||||||
|
rev = "0d9540b13ffcd7cd44cc361b8744b93d88aa76ba";
|
||||||
|
sha256 = "05zwhv8ffzrfdzqbsb4zm4kjdbjxqy5jh9r83fic0qpk2mkvc2i2";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = [ autoreconfHook ];
|
||||||
|
|
||||||
|
configureFlags = ["--enable-module-recovery" "--disable-jni" "--enable-experimental" "--enable-module-ecdh" "--enable-benchmark=no" ];
|
||||||
|
|
||||||
|
meta = with stdenv.lib; {
|
||||||
|
description = "Optimized C library for EC operations on curve secp256k1";
|
||||||
|
homepage = "https://github.com/bitcoin-core/secp256k1";
|
||||||
|
license = with licenses; [ mit ];
|
||||||
|
maintainers = with maintainers; [ nixbitcoin ];
|
||||||
|
platforms = with platforms; unix;
|
||||||
|
};
|
||||||
|
}
|
16
pkgs/joinmarket/urldecode/default.nix
Normal file
16
pkgs/joinmarket/urldecode/default.nix
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{ lib, buildPythonPackage, fetchPypi }:
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "urldecode";
|
||||||
|
version = "0.1";
|
||||||
|
|
||||||
|
src = fetchPypi {
|
||||||
|
inherit pname version;
|
||||||
|
sha256 = "0w8my7kdwxppsfzzi1b2cxhypm6r1fsrnb2hnd752axq4gfsddjj";
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "A simple function to decode an encoded url";
|
||||||
|
homepage = "https://github.com/jennyq/urldecode";
|
||||||
|
maintainers = with maintainers; [ nixbitcoin ];
|
||||||
|
};
|
||||||
|
}
|
@ -13,7 +13,8 @@ static char *allowed_netns[] = {
|
|||||||
"nb-lnd",
|
"nb-lnd",
|
||||||
"nb-lightning-loop",
|
"nb-lightning-loop",
|
||||||
"nb-bitcoind",
|
"nb-bitcoind",
|
||||||
"nb-liquidd"
|
"nb-liquidd",
|
||||||
|
"nb-joinmarket"
|
||||||
};
|
};
|
||||||
|
|
||||||
int is_netns_allowed(char *netns) {
|
int is_netns_allowed(char *netns) {
|
||||||
|
12
test/base.py
12
test/base.py
@ -102,6 +102,14 @@ def run_tests(extra_tests):
|
|||||||
|
|
||||||
assert_running("onion-chef")
|
assert_running("onion-chef")
|
||||||
|
|
||||||
|
assert_running("joinmarket")
|
||||||
|
machine.wait_until_succeeds(
|
||||||
|
log_has_string("joinmarket", "P2EPDaemonServerProtocolFactory starting on 27184")
|
||||||
|
)
|
||||||
|
machine.wait_until_succeeds(
|
||||||
|
log_has_string("joinmarket-yieldgenerator", "Failure to get blockheight",)
|
||||||
|
)
|
||||||
|
|
||||||
# FIXME: use 'wait_for_unit' because 'create-web-index' always fails during startup due
|
# FIXME: use 'wait_for_unit' because 'create-web-index' always fails during startup due
|
||||||
# to incomplete unit dependencies.
|
# to incomplete unit dependencies.
|
||||||
# 'create-web-index' implicitly tests 'nodeinfo'.
|
# 'create-web-index' implicitly tests 'nodeinfo'.
|
||||||
@ -150,6 +158,10 @@ def run_tests(extra_tests):
|
|||||||
"export $(cat /secrets/backup-encryption-env); duplicity list-current-files 'file:///var/lib/localBackups'",
|
"export $(cat /secrets/backup-encryption-env); duplicity list-current-files 'file:///var/lib/localBackups'",
|
||||||
"secrets/lnd-seed-mnemonic",
|
"secrets/lnd-seed-mnemonic",
|
||||||
)
|
)
|
||||||
|
assert_matches(
|
||||||
|
"export $(cat /secrets/backup-encryption-env); duplicity list-current-files 'file:///var/lib/localBackups'",
|
||||||
|
"secrets/jm-wallet-seed",
|
||||||
|
)
|
||||||
assert_matches(
|
assert_matches(
|
||||||
"export $(cat /secrets/backup-encryption-env); duplicity list-current-files 'file:///var/lib/localBackups'",
|
"export $(cat /secrets/backup-encryption-env); duplicity list-current-files 'file:///var/lib/localBackups'",
|
||||||
"var/lib/bitcoind/wallet.dat",
|
"var/lib/bitcoind/wallet.dat",
|
||||||
|
@ -57,6 +57,15 @@ import ./make-test.nix rec {
|
|||||||
# needed to test macaroon creation
|
# needed to test macaroon creation
|
||||||
environment.systemPackages = with pkgs; [ openssl xxd ];
|
environment.systemPackages = with pkgs; [ openssl xxd ];
|
||||||
|
|
||||||
|
services.joinmarket.enable = true;
|
||||||
|
services.joinmarket.yieldgenerator = {
|
||||||
|
enable = true;
|
||||||
|
customParameters = ''
|
||||||
|
txfee = 200
|
||||||
|
cjfee_a = 300
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
# to test that unused secrets are made inaccessible by 'setup-secrets'
|
# to test that unused secrets are made inaccessible by 'setup-secrets'
|
||||||
systemd.services.generate-secrets.postStart = ''
|
systemd.services.generate-secrets.postStart = ''
|
||||||
install -o nobody -g nogroup -m777 <(:) /secrets/dummy
|
install -o nobody -g nogroup -m777 <(:) /secrets/dummy
|
||||||
|
Loading…
Reference in New Issue
Block a user