--- /dev/null
+
+WALLET = wallet
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+LATEX = pdflatex -halt-on-error
+QRENCODE = qrencode
+XPDF = xdg-open
+
+.PHONY: all clean pdf run
+
+all: $(WALLET).pdf
+
+clean:
+ rm -f $(WALLET).aux
+ rm -f $(WALLET).log
+ rm -f $(WALLET).lof
+ rm -f $(WALLET).lol
+ rm -f $(WALLET).lot
+ rm -f $(WALLET).pdf
+ rm -f $(WALLET).toc
+ rm -f $(WALLET).out
+ rm -f $(WALLET).tex
+ rm -f $(WALLET).png
+
+pdf: $(WALLET).pdf
+
+run: pdf
+ $(XPDF) $(WALLET).pdf
+
+$(WALLET).pdf: $(WALLET).tex $(WALLET).png
+ $(LATEX) $(WALLET)
+
+$(WALLET).tex: $(WALLET).json
+ ./gentex.pl $< >$@
+
+$(WALLET).png: $(WALLET).json
+ $(QRENCODE) -r $< -o $@ -s 4
+
+
--- /dev/null
+#!/usr/bin/env perl
+
+use warnings;
+use strict;
+use autodie;
+
+use JSON::MaybeXS qw(decode_json);
+use Template::Alloy;
+
+my $filepath = shift or die "Usage: $0 wallet.json\n";
+
+my $in = do { open(my $fh, '<', $filepath); local $/; <$fh> };
+my $wallet = decode_json($in);
+
+use Data::Dumper;
+print STDERR Dumper $wallet;
+
+my $qrcode = $filepath;
+$qrcode =~ s/\.json$/.png/;
+
+my $template = do { local $/; <DATA> };
+
+my $doc;
+my $t = Template::Alloy->new;
+$t->process(\$template, { %$wallet, qrcode => $qrcode }, \$doc);
+
+print $doc;
+exit;
+
+__DATA__
+\documentclass[letterpaper]{article}
+
+\author{Bitcoin Multisig Wallet Backup File}
+\date{\today}
+\title{[% name %]}
+
+\usepackage[margin=1in]{geometry}
+\usepackage{graphicx}
+
+\begin{document}
+
+\maketitle
+
+\section{General Information}
+
+\begin{itemize}
+ \item Quorum: \texttt{[% quorum.requiredSigners %] of [% quorum.totalSigners %]}
+ \item Address type: \texttt{[% addressType %]}
+ \item Network: \texttt{[% network %]}
+ \item Starting address index: \texttt{[% startingAddressIndex %]}
+\end{itemize}
+
+\subsection{Keys}
+
+[%- FOR key IN extendedPublicKeys %]
+\subsubsection{Cosigner [% loop.count %]}
+
+\begin{itemize}
+ \item Label: \texttt{[% key.name %]}
+ \item Master fingerprint: \texttt{[% key.xfp %]}
+ \item Derivation path: \texttt{[% key.bip32Path %]}
+ \item Extended public key: \texttt{[% key.xpub.replace('(.{60})', '$1 \\\\ ') %]}
+\end{itemize}
+
+[%- END %]
+
+\newpage
+\section{QR Code}
+
+\begin{figure}[hp]
+ \centering
+ \includegraphics{[% qrcode %]}
+\end{figure}
+
+\subsection{Directions}
+
+Scan this QR code to quickly import the wallet backup file into a digital
+device. \\
+\\
+The data file can be used by Caravan software, a stateless multisig coordinator: \\
+\texttt{https://unchained-capital.github.io/caravan/} \\
+\\
+The data contained within the wallet backup file can also be entered into
+other wallet software, such as Electrum, Sparrow and Specter.
+
+\end{document}
+
+% \ref{sec:foo}
+% \label{sec:limitations}
+% \footnote{ ... }
+
+% \begin{figure}[hp]
+% \includegraphics[scale=0.45]{fig1.pdf}
+% \caption{Activity diagram.}
+% \label{fig:activity1}
+% \end{figure}
+
+% \begin{lstlisting}[caption=Bar]
+% ...
+% \end{lstlisting}
+
+% \begin{center}
+% \begin{tabular}{r|l}
+% Type & Value \\
+% \hline
+% byte & {\tt0x01} (literal) \\
+% String & Player's name \\
+% String & Message
+% \end{tabular}
+% \end{center}
+
+% \newpage
+% \appendix
+
+% \begin{itemize}
+% \item ...
+% \end{itemize}
+