# Background
[DID DHT](https://github.com/TBD54566975/did-dht/blob/main/README.md) is a new service that, among other things, allows a global way to broadcast DID-authenticated messages using [libp2p PubSub](https://docs.libp2p.io/concepts/pubsub/overview/).
# Gossip
DID DHT exposes a set of APIs that enable you to create and send messages to a gossip topic within the `diddht` namespace. This means anyone in the world can set up a libp2p gossipsub client and participate in listening to and broadcasting messages if they use the namespace and 'join' a common topic.
The service enforces a common message format across all topics:
```go
type SignedRecord struct {
Payload map[string]any `json:"payload,omitempty"`
JWS string `json:"jws,omitempty"`
}
```
The `payload` is any JSON object. The JWS is a [RFC 7515](https://datatracker.ietf.org/doc/html/rfc7515) compliant object using [compact serialization](https://datatracker.ietf.org/doc/html/rfc7515#section-3.1). The data is canonicalized using [JCS](https://www.rfc-editor.org/rfc/rfc8785) before signing for consistency purposes. The `SignedRecord` object combines both the raw payload with the JWS, since the JWS contains claims, such as the `iss`, `iat`, and `jti` properties that are not necessary in the `payload` itself.
If this becomes too cumbersome we may explore a [detached payload option](https://datatracker.ietf.org/doc/html/rfc7515#appendix-F) in the future.
The `iss` of the JWS **MUST** be a DID, and the `kid` in the JWS's protected header must be the identifier of a [`verificationMethod`](https://www.w3.org/TR/did-core/#verification-methods) in the corresponding DID Document.
# Usage in tbDEX
The first usage of the DID DHT in tbDEX is to enable PFI discovery. PFI discovery means giving PFIs a way to broadcast that that they offer exchanges for certain currency pairs.
## Writing to a Topic
For example, an example broadcast message within the `diddht/pfi` namespace may look as follows:
- A PUT to `/gossip` to create the topic `pfi`, with body. This enables listening from and posting to the topic:
```json
{
"topic": "pfi"
}
```
- A PUT to `/gossip/pfi` to message the topic, with body:
```json
{
"payload": {
"currencyPairs": [
"BTC/USDT",
"ETH/USDT"
],
"endpoint": "https://tbdex.website",
"pfiName": "tbDEX-PFI"
},
"jws": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKcmRIa2lPaUpQUzFBaUxDSmpjbllpT2lKRlpESTFOVEU1SWl3aWVDSTZJbUkwUWtkSVdtUnRkelJCTWtGeE9USmhWRzh4VWkxaE1YTm5ka3QxVDFwMFRWOTRaMG8yTWxadlNHOGlMQ0poYkdjaU9pSkZaRVJUUVNKOSMwIiwidHlwIjoiSldUIn0.eyJjdXJyZW5jeVBhaXJzIjpbIkJUQy9VU0RUIiwiRVRIL1VTRFQiXSwiZW5kcG9pbnQiOiJodHRwczovL3RiZGV4LndlYnNpdGUiLCJpYXQiOjE2OTAyMzg4NTQsImlzcyI6ImRpZDpqd2s6ZXlKcmRIa2lPaUpQUzFBaUxDSmpjbllpT2lKRlpESTFOVEU1SWl3aWVDSTZJbUkwUWtkSVdtUnRkelJCTWtGeE9USmhWRzh4VWkxaE1YTm5ka3QxVDFwMFRWOTRaMG8yTWxadlNHOGlMQ0poYkdjaU9pSkZaRVJUUVNKOSIsInBmaU5hbWUiOiJ0YkRFWC1QRkkifQ.6DW4P4ZpVFaliWGjdnlPzmCjH9dNqMafDb2Lc7iIQNJrgcLcS-lgoYqJBzjQaT1WWnfIPNgIcUAkxq9PWzX9Cw"
}
```
The decoded JWS payload is as follows:
```json
{
"alg": "EdDSA",
"kid": "did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6ImI0QkdIWmRtdzRBMkFxOTJhVG8xUi1hMXNndkt1T1p0TV94Z0o2MlZvSG8iLCJhbGciOiJFZERTQSJ9#0",
"typ": "JWT"
}
```
```json
{
"currencyPairs": [
"BTC/USDT",
"ETH/USDT"
],
"endpoint": "https://tbdex.website",
"iat": 1690238854,
"iss": "did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6ImI0QkdIWmRtdzRBMkFxOTJhVG8xUi1hMXNndkt1T1p0TV94Z0o2MlZvSG8iLCJhbGciOiJFZERTQSJ9",
"pfiName": "tbDEX-PFI"
}
```
## Reading from a Topic
Any other DID DHT service, besides where the message was published AND any gossip client configured to listen to `diddht/pfi` will see the `SignedRecord` JSON payload.
Conformant clients will verify the JWS, resolving the DID from the `iss` property, and finding the associated `kid` from the protected header's `kid` property. If the JWS does not validate, the message will be dropped.
## More Useful APIs
We can surface more useful APIs in the DID DHT service that can fulfill certain queries, such as answering _"Which PFIs are available for X trading pair?"_
A sample API may be...
- GET `/gossip/pfi?pair=USD-BTC`
A sensible response would be a list of PFIs and their associated information, which could be pulled from prior gossip messages and/or the DHT itself:
```json
{
"pair": "USD-BTC",
"pfis": [
{
"did": "did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6ImI0QkdIWmRtdzRBMkFxOTJhVG8xUi1hMXNndkt1T1p0TV94Z0o2MlZvSG8iLCJhbGciOiJFZERTQSJ9"
"pfiName": "tbDEX-PFI",
"endpoint": "https://tbdex.website"
},
{
"did": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp"
"pfiName": "ACME PFI",
"endpoint": "https://acme.inc"
}
]
}
```