pinkie

A decentralized, non-custodial web-wallet for Handshake.

Stars
9

Pinkie-Swear

A protocol to store an encrypted private key for an HNS domain name in a TXT record inside that that name's root zone resource. Users can access their domain from any web browser (or nodejs console) using just the domain name and a strong password. Once the key has been retrieved and decrypted client-side, the name's root zone resource can be updated by creating an incomplete transaction signed with SIGHASH_SINGLE | SIGHASH_ANYONECANPAY. This allows a second party (the server) to pay the fee for the UPDATE and broadcast on behalf of the user.

The encryption currently relies on 10,000,000 iterations of PBKDF2 with a 128-bit salt and SHA256 PRF. Passwords should be at least 20 characters. Decryption takes about 10 seconds in Firefox and about 5 seconds in nodejs.

The protocol works as follows:

Step 1: Generate key, encrypt key

  • User generates a 24-word mnemonic seed phrase.
    • This can be generated by the app or by external process and pasted into the app.
  • User enters a strong password which is used to encrypt the seed phrase.
  • The encrypted blob is serialized as a base64 string in a TXT record in HNS Resource format.
  • The first receive address at index 0 is derived and output to the user.

Step 2: Insert encrypted key into HNS root zone resource for user's domain

  • The app outputs HNS resource data as both JSON (to be used with hsw-rpc sendupdate
    and as a hex blob (for use with Namebase's "Advanced DNS" field).
  • This UPDATE must be confirmed in the HNS blockchain before continuing.

Step 3: Transfer the name to the newly generated key

  • User requests a transfer of the name to the address computed in step 1 from Namebase,
    or completes the transfer manually with hsd.

Step 4: "Log in" and update additional records

The user can now update their root zone data from the webapp using only their domain name and password:

  • Client requests getnameresource for their name from the server.
    The response is JSON and contains a TXT record with the encrypted mnemonic phrase (from step 2).
  • Client decrypts the mnemonic with the user's passphrase.
  • Client adds additional TXT records to their name's HNS resource.
  • Client requests from the server the current owner (UTXO) of their name.
  • Client constructs a 1-input, 1-output transaction with a new UPDATE covenant
    that contains the updated HNS resource and signs it using the decrypted private key
    and sighash flags SINGLE | ANYONECANPAY.
  • Client sends this partially-signed transaction to the server as a seriazlied hex string.
  • Server adds an additional input and output to pay the fee for this transaction, signs it with SIGHASH_ALL and broadcasts.

Installation:

git clone https://github.com/pinheadmz/pinkie
cd pinkie
npm i

The Pinkie Swear server requires a peer dependency of hsd. The hsd library must be available in global node_modules on your system and it is assumed that an hsd full node is running with a sufficiently funded wallet. To configure a Pinkie Swear for mainnet, see this commit.

Additional hsd wallet and full node configuration settings are documented here and in the API-docs.

Building:

The client code is written in the context of nodejs but can be compiled for the browser using bpkg (included as dependency). It can be compiled with or without being minified/uglified for either smaller transport, or debugging. Paranoid users should use the dev mode if they are worried about interference from the uglify plugin.

These commands compile the code from lib/ into a git-ignored file html/js/hnswallet-browser.js which is requested by the html page.

Either way, large modules from the hsd library are included in the payload for wallet structure, transaction primitives, and message signing and it is a large file.

# compact
npm run build

# debug / auditable
npm run build-dev

Running:

node bin/pinkie.js

This command will start the webserver (by default on regtest at http://127.0.0.1:8000) that serves the client front-end and also communicates with the hsd full node on the back-end.

Warning:

The wallet-interfacing server does not have any checks or rate-limits yet and overall security of the coinjoin protocol has not yet been audited.

Demonstration:

https://youtu.be/7WIBXMVQe5U