Skip to content

HIP-0013: Profile Data and Wallet Addresses in TXT Records #63

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions HIP-0013.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# HIP-0013: Profile Data and Wallet Addresses in TXT Records

```
Number: HIP-0013
Title: Profile Data and Wallet Addresses in TXT Records
Type: Standards
Status: Draft
Authors: @aoxborrow, @0xStefan, @Falci
Created: 2024-03-14
```

## Abstract

This document introduces IDNS (Identity-DNS), a standard for storing portable profile data and crypto wallet addresses securely within DNS TXT records.

## Motivation

Handshake holds significant potential for decentralized identity and wallet naming, but so far the focus has primarily been on websites. This proposal aims to establish a new and improved standard designed to encourage the development of decentralized identity applications for Handshake.

### Domains as Portable Identities
By attaching profile data such as a name, avatar, and bio, domains can act as portable online identities. This "bring-your-own-identity" approach, where users control their own data, has been adopted by platforms like [BlueSky](https://atproto.com/specs/handle), [Thunderbolt](https://www.spaceship.com/thunderbolt), and [Farcaster](https://docs.farcaster.xyz/learn/architecture/ens-names), which all utilize domains over traditional usernames.

Domains help overcome the scarcity of desirable namespace on social networks, allowing for more personalized and meaningful identifiers. For example, a proud Texan might choose `@richard.tx` over settling for `@richard_214`. Similarly, verified domains like `@nike.com` establish true authenticity, a clear advantage over fallible methods like blue checkmarks.

### Domains for Wallet Naming
In the same way that domains provide human-readable names for IP addresses, they can also map human-readable names to lengthy cryptocurrency addresses. Wallet naming makes it easy to send crypto to a friend or donate to a worthy cause. As crypto adoption grows, domains must evolve to support the payment rails of the future. Wallet naming continues to be the primary driver of adoption for blockchain naming systems like [ENS](https://docs.ens.domains/web/resolution).

### Advantages of TXT Records
Utilizing DNS offers practical benefits over blockchain-based systems:
* **Compatible** - Works with both Handshake and ICANN domains across different registrars and DNS providers.
* **Economical** - No gas fees needed for data storage or ongoing management.
* **Ease of Use** - Simple for both domain owners and developers. No specialized blockchain knowledge required.
* **Security** - DNSSEC ensures data integrity, while proven DNS infrastructure guarantees speed & availability.

### DNS: A Strategy for Adoption
This specification is fully compatible with ICANN domains, which dramatically broadens the potential user base. By growing the identity use-case for DNS domains, we can position Handshake as the superior alternative – private, decentralized, and censor-resistant. By building tools and services around IDNS that support both HNS and DNS domains, we can reach a much wider audience beyond the crypto community.

## TXT Specification

IDNS TXT records begin with **`IDNS1`** (version 1), and use the following format containing a record type, key, and value:

<pre><code><b>IDNS1 &lt;type&gt;:&lt;key&gt;=&lt;value&gt;</b>
</code></pre>

IDNS TXT records can contain one or more records in key=value pairs, separated by spaces:
<pre><code><b>IDNS1</b> profile:avatar=<ins>http://pic.com/me.png</ins> service:com.twitter=<ins>aoxborrow</ins>
</code></pre>

Records that contain spaces must be quoted. Quotes in the record data can be escaped with a backslash:
<pre><code><b>IDNS1</b> profile:location=<ins>"Berkeley, CA"</ins> profile:bio=<ins>'I\'m a passionate advocate for domain innovation.'</ins></code></pre>

### Profile Records (`profile`)
Human-readable user profile text data.
- **`<key>`** The profile record name, any text key is valid, no spaces.
- **`<value>`** The profile record data.
<pre><code><b>IDNS1 profile:&lt;key&gt;=&lt;value&gt;</b>

<i>Examples:</i>
IDNS1 profile:name=aox
IDNS1 profile:avatar=https://hns.id/domain/aox.hns/avatar.png
IDNS1 profile:location="Berkeley, CA"
IDNS1 profile:[email protected]
</code></pre>

### Service Records (`service`)
Service keys must be made up of a reverse dot notation for a namespace which the service owns, for example, DNS names (e.g. .com, .io) or HNS name (i.e. .hns). Service Keys must contain at least one dot. See [EIP-634](https://eips.ethereum.org/EIPS/eip-634#service-keys).
- **`<key>`** A service key associated with the user, e.g. `com.github`.
- **`<identifier>`** Identifier for the service, e.g. Github username.
<pre><code><b>IDNS1 service:&lt;key&gt;=&lt;identifier&gt;</b>

<i>Examples:</i>
IDNS1 service:com.twitter=aoxborrow
IDNS1 service:com.github=0xstefan
IDNS1 service:io.keybase=pinheadmz
IDNS1 service:.hnschat=skmo
</code></pre>

### Wallet Records (`wallet`)
Cryptocurrency wallet addresses. Uses [SLIP44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) to specify different blockchains.
- **`<cointype>`** The type of cryptocurrency, using SLIP44 cointype symbol or number, e.g. `hns` or `5353`
- **`<address>`** Wallet address for the specific cryptocurrency.
<pre><code><b>IDNS1 wallet:&lt;cointype&gt;=&lt;address&gt;</b>

<i>Examples:</i>
IDNS1 wallet:btc=1dvf5aqkvrvjeasrudilatgwlbgfwa9ovy
IDNS1 wallet:hns=hs1qshuyulxra3pqpwr40303t8pn79232zztuk4qgz
IDNS1 wallet:5353=hs1qshuyulxra3pqpwr40303t8pn79232zztuk4qgz
IDNS1 wallet:eth=0xa08aba528da538cd3547a73c93d51b90201294b6
</code></pre>


### Contenthash Records (`contenthash`)
A content hash or address for distributed networks like IPFS. See [ENSIP-7](https://docs.ens.domains/ensip/7).
- **`<protocol>`** Distributed network protocol name, e.g. `ipfs`. **NOTE:** this is not used for resolution
- **`<address>`** Content address or content hash for distributed network.
<pre><code><b>IDNS1 contenthash:&lt;protocol&gt;=&lt;address&gt;</b>

<i>Examples:</i>
IDNS1 contenthash:ipfs=c04dfad360be65ba134aab7d07ec59f0547a73ef3168
IDNS1 contenthash:swarm=d191eb26786769f580809256b4685ef316805265ea1
</code></pre>


### Auth Records (`auth`)
Authentication provider for use with "Login with Domain." See [Handshake Login](https://learn.namebase.io/development/guides/handshake-login/using-handshake-login#set-up-a-custom-identity-manager). (WIP)
- **`<provider>`** Identity provider URL.
- **`<fingerprint>`** Provider-specific fingerprint.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the WIP tag, but to add my 2¢ I hope this fingerprint part can be a bit more flexible. By only specifying the hash, we're locking into a single digest algo forever. I remember chatting with nb folks when they launched Handshake Login, but sadly don't have that history anymore.

Current nb's standard also includes a prefix/deviceId (source):

{prefix}._auth.{name}    TXT    v={x};fingerprint={hash};

And https://id.htools.work/ extends on that to support WebAuthn (security keys), etc. while being backward compatible like:

{prefix}._auth.{name}    TXT    v={x};fingerprint={hash};keyId={keyid};pubKey={pubkey}

example live record:

6bb41cddff1861dd._auth.noodleai. 5 IN	TXT	"v=0;fingerprint=efdaab62cdcd698f8d9a3c862ef431eb4085242d8fb4ac2e9ca1ebbdee2f4e74;keyId=TvCvFOBa5T2cAjgE380NjlDRW38RLuOP20XvL0csB8epbwnoyFzSlWG8y22Lx7cuDhqIeE8MDG2rFOShdRdSPw;pubKey=MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2uj6y+wk4MjYbloWg1X+GatakxVJGH9UtRKbEP" "Tey5luedoPtHnJhTP4rpfpvE4odF0GszyF7exJ4hqcIT5itg"

tl;dr: some flexibilty for future changes with hash algos, extra fields and versioning would be nice.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having flexibility on hash algos, and future proofing (quantum) is needed as well (not a nice to have).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rithvikvibhu @jeefave is our guy who did the original NB OIDC. would be very open to contribution from either of you. what is the purpose for using the device/prefix as the subdomain host, and could it be moved to part of the TXT if there is room? e.g.
HDNS1 auth:device={prefix} auth:fingerprint={hash} auth:keyid={keyid} auth:pubkey={pubkey}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iirc the idea behind the prefix was that since DNS doesn't* give you ALL records at once, adding a long enough pseudo-random prefix would mean nobody could enumerate find a list of all your devices. So if your laptop and phone stores keys, nobody can find the 2 records except the devices themselves since they store the device id locally in the browser.

When putting it on chain, it doesn't make a lot of sense since all records are already visible. So we do lose some privacy. Need to think about the format a bit more and honestly I don't really remember much about the protocol. btw hey John, been a while!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the initial NB OIDC protocol definition contains a prevision to customize the hash algos (here). In the context of OAuth, the underlaying OIDC server will need to cater for the desired algorithms (currently it is hardcoded). It could be useful to explore how this could be extended to allow signing with metamask or others.

The TXT format was inspired by these ietf drafts (1 and 2) where tag=value are separated by ";" and where values can be either text or base64 encoded strings depending on the nature of the tag.

I can confirm that the {prefix} subdomain aims to keep the list of the devices private because at the moment each devices generate their own private key. It seems like you remember quite well @rithvikvibhu :). Some similar mechanism could be leveraged to hide the list of services and profile infos if there are any privacy or security concerns? Another consideration is that using subdomains provides an elegant way to partition the data. It would mandate using DNSSEC. What are the benefits to store these data on chain?

What are your thoughts regarding this format?

<typehash>._hdns.<name> TXT <key>=<value>
servicehash1._hdns.name TXT v=0;identifier=aoxborrow
servicehash2._hdns.name TXT v=0;identifier=aoxborrow;picture=aHR0cHM6Ly9lbmNyeXB0ZWQtdGJuMC5nc3RhdGljLmNvbS9pbWFnZXM/cT10Ym46QU5kOUdjU1lzY2ZVQlVicXdHZF9ESFZoRy1aakNPRDdNVXB4cDR1aE5lN3RvVWc0dWcmcw==

Currently the HIP allows to define multiple provider fingerprints but the handshake login protocol sets the private key provider (idmanager) as a 1-1 association with its identity/domain. Relying parties are unaware of the signing party so identities can delegate to their preferred implementation. What use cases would require multiple id managers and how would they be resolved by the authication party?

image

<pre><code><b>IDNS1 auth:&lt;provider&gt;=&lt;fingerprint&gt;</b>

<i>Examples:</i>
IDNS1 auth:id.namebase.io=b9feeee2b4ad5c04dfad360be65ba134aab7d
IDNS1 auth:id.htools.work=360be65ba134aab7d07ec59f0547a73360be6
IDNS1 auth:auth.varo.domains=6786769f580809256b4685ef316805265ea1e
</code></pre>

### TTL & Caching
Applications should respect the `ttl` setting of IDNS TXT records and cache the record data accordingly. Most profile records should have a long TTL, at least one hour (`3600`) or more. For wallet records, in order to replicate the behavior of a [HIP-2 server](https://github.com/pinheadmz/hip2-server), use a short TTL and rotate the wallet addresses frequently.

### TLD Records & DNSSEC
Handshake TLDs are encouraged to put IDNS TXT records directly onchain for the bare TLD. If using delegation (nameservers), DNSSEC is required. DNSSEC is required for all domains.


## References
* Stefan's Original HIP-0013 - TXT Record Naming Standards https://github.com/handshake-org/HIPs/pull/46
* EIP-634: Storage of text records in ENS https://eips.ethereum.org/EIPS/eip-634
* RFC 1464 https://datatracker.ietf.org/doc/html/rfc1464
* Handshake OIDC Authentication https://learn.namebase.io/development/guides/handshake-login/handshake-based-oidc-authentication-protocol
* HTools Handshake Login https://github.com/htools-org/handshake-login
* James Stevens' Wallet IDs in DNS https://github.com/james-stevens/wallet-ids-in-dns
* A proposal for cryptocurrency addresses in DNS https://ma.ttias.be/proposal-cryptocurrency-addresses-dns
* Simplifying Bitcoin Addresses Using DNS https://bitcoinmagazine.com/technical/simplifying-bitcoin-addresses-dns
* OpenAlias https://openalias.org
* DNSLink https://dnslink.dev