%\documentclass{article} \documentclass[a4paper,12pt]{article} \usepackage[english]{babel} %\usepackage[a4paper,top=20mm,bottom=20mm,left=20mm,right=20mm,marginparwidth=1.75cm]{geometry} \usepackage[a4paper,top=20mm,bottom=20mm,left=20mm,right=20mm]{geometry} \usepackage{array} \usepackage[framemethod=tikz]{mdframed} \usepackage{makecell} \usepackage{enumitem} \usepackage{xcolor} \usepackage{parskip} \newcolumntype{P}[1]{>{\centering\arraybackslash}p{#1}} \newcolumntype{M}[1]{>{\centering\arraybackslash}m{#1}} \newenvironment{changemargin}[2]{% \begin{list}{}{% \setlength{\topsep}{0pt}% \setlength{\leftmargin}{#1}% \setlength{\rightmargin}{#2}% \setlength{\listparindent}{\parindent}% \setlength{\itemindent}{\parindent}% \setlength{\parsep}{\parskip}% }% \item[]}{\end{list}} % Useful packages \usepackage{amsmath} \usepackage{graphicx} \usepackage[colorlinks=true, allcolors=blue]{hyperref} %\title{Your Paper} %\author{You} \begin{document} %\maketitle %\begin{abstract} %Your abstract. %\end{abstract} \begin{center} {\Huge \textsc{NGI POINTER: Peer-to-Peer Payments}} \end{center} \section{Context} For the NGI POINTER programme, the GNU Taler team developed age-restricted payments, peer-to-peer (P2P) payments and a proof-of-concept ability to extend GNU Taler with escrow functionality for privacy-preserving auctions. This document provides some details on the state of the P2P payment functionality. \section{Overview} We implemented two styles of P2P payments: {\bf push payments} where a user sends money to another Taler wallet (which can then accept the payment), and {\bf pull payments} where a user sends an invoice to another Taler wallet (which can then pay the invoice). Both styles of payment only require one asynchronous uni-directional secure communication between the wallets to make the payment. The information that is exchanged is in both cases a short {\tt taler://}-URI which allows the wallet to obtain further details from the payment service provider. These further details include the contract/invoice that the payment is for. The contract/invoice is stored encrypted at the exchange and thus cannot be learned by the exchange. The actual P2P payment works by having the initiator wallet first communicate with the Taler exchange to setup the payment. Then the Taler URI is communicated to the other wallet, for now usually via QR code or NFC transmission; however, users could also copy the URI to the clipboard and exchange it via some (secure) messenger. Upon receiving the URI, the other wallet then again interacts with the exchange to obtain more details and complete the payment. If the recipient of a push payment does not accept the payment (say because the message was lost in transmission, or they do not like the attached contract terms) the money is automatically refunded to the payer after some expiration date is reached. \section{Technical details} P2P payments always work by establishing a {\bf purse} at the exchange. A purse has an expiration date, target amount, minimum age, associated business contract (or invoice), an actual balance and two public-private key pairs representing permissions to operate on the purse. For a push payment, the wallet of the sending user creates a purse (with contract and expiration time) and immediately ensures that the balance of the purse is the target amount. The payer then sends the merge-capability key of the purse to the payee. The payee can then use the merge-capability key to merge (move) the balance of the purse into a KYCed reserve of the receiving wallet. A KYCed reserve basically is a long-term public-private key pair that identifies a wallet and a user at an exchange, ensuring income transparency. Once the money is in the reserve, the wallet can then use the reserve private key to withdraw fresh coins. When invoicing, the initiator again creates a purse, but this time does not put any money into it and keeps the merge capability key private. The initiator wallet instead immediately specifies its own KYCed reserve as the one the purse should be merged into. The initiator then shares a contract-download capability key with the payer. The payer downloads the contract (including the purse public key) and can then decide to put money into the purse. Once the purse balance reaches the target amount, it is then automatically merged with the initiator's reserve. The initiator's wallet (long) polls the reserve and withdraws the funds as soon as they become available. The protocol and implementation includes a few refinements, like fees to be paid to the exchange for managing a purse and age-restrictions on the coins used to pay an invoice. \section{Future Work} The following features (from tiny to major) have been discussed in the team and ought to be implemented as part of future work. \begin{itemize} \item {\bf Wallets:} The wallet UIs currently do not allow the user to actually specify any age-restrictions on the payer when sending P2P pull payment requests (invoicing). This mostly is about adding one more drop-down widget. \item {\bf Wallets:} The wallet UIs currently do not allow the user to actually specify the expiration date for the purse. Instead, the duration is hard-coded to a few hours (likely too short). This mostly is about adding one more input field. \item {\bf Auditor:} The Taler auditor was extended to support P2P transactions in its audits, but the code has not been adequately tested (no fault injection). \item {\bf Exchange:} P2P payments currently only work if both wallets are using the same exchange. If multiple exchanges operate in the same currency domain and the recipient has made their (expensive) KYC process at one exchange and the payer has withdrawn from the other, a direct payment between the wallets is not possible right now. We envision federation protocol using periodic aggregated (``wad'') payments between exchanges should be added to support P2P payments involing multiple exchanges in the future. \item {\bf Mailbox (NEW):} Currently, sending the payment URI is largely left to the user. We would like to implement a ``mailbox'' service for Taler wallets that would enable wallets to asynchronously exchange URIs over the Internet. Once a wallet knows the mailbox address of another wallet (which would include a public key to encrypt messages to), the user would no longer be required to manually exchange the QR code. \item {\bf TalDir (NEW):} To lookup the mailbox address of another wallet, we would like to implement a directory service that maps existing addresses like e-mail addresses, phone numbers or accounts in messengers or social media platforms to a mailbox. When establishing the directory service entry, the directory service would validate that the user registering the wallet has control over the respective address. Naturally, the directory service would need to be trusted to return the correct mapping. \item Both the mailbox and the directory service operators could themselves be paid via Taler for their service. That should help ensure a high quality of service from those operators. Naturally, using the mailbox or the directory service would be optional. \item {\bf Messaging:} In the long term, we would like to see more direct integration of Taler payment functionality with messaging applications, especially for spam prevention (``The recipient has configured its software to demand a payment of 50 cents before displaying a message from an unknown sender to the user. If they like your message, they promise they would refund this attention fee. Do you want to pay to have your message shown? (Y/N)''). \end{itemize} \section{Links} The design is documented at \url{https://docs.taler.net/design-documents/013-peer-to-peer-payments.html}. The main implementation parts are distributed over various code locations: \begin{description} \item[Peer-to-peer payment operations in wallet:] \url{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-core/src/operations/pay-peer.ts} \item[Database schema with p2p state in it:] \url{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-core/src/db.ts#n2065} \item[Peer-to-peer transactions in the transaction list type declarations:] \url{https://git.taler.net/wallet-core.git/tree/packages/taler-util/src/transactions-types.ts#n251} \item[WebExtension UI stuff related to peer-to-peer:] \url{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-webextension/src/cta/InvoiceCreate}, \url{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-webextension/src/cta/InvoicePay} \item[Exchange] \url{https://git.taler.net/exchange.git/tree/src/exchange/}, specifically {\tt taler-exchange-httpd\_purses\_*.c}, {\tt taler-exchange-httpd\_reserves\_purse\_*.c}, {\tt taler-exchange-httpd\_contract.*}, {\tt taler-exchange-expire.c} (plus related changes in the database, client libraries, history, auditor), and the main test case at {\tt https://git.taler.net/exchange.git/tree/src/testing/test\_exchange\_p2p.c} \end{description} \end{document}